xref: /haiku/src/tests/add-ons/translators/stxttranslator/STXTTranslatorTest.cpp (revision 893988af824e65e49e55f517b157db8386e8002b)
1 // STXTTranslatorTest.cpp
2 #include "STXTTranslatorTest.h"
3 #include <cppunit/Test.h>
4 #include <cppunit/TestCaller.h>
5 #include <cppunit/TestSuite.h>
6 #include <stdio.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include <image.h>
10 #include <Translator.h>
11 #include <TranslatorFormats.h>
12 #include <TranslatorRoster.h>
13 #include <Message.h>
14 #include <View.h>
15 #include <Rect.h>
16 #include <File.h>
17 #include <DataIO.h>
18 #include <Errors.h>
19 #include <OS.h>
20 #include "TranslatorTestAddOn.h"
21 
22 // Suite
23 CppUnit::Test *
24 STXTTranslatorTest::Suite()
25 {
26 	CppUnit::TestSuite *suite = new CppUnit::TestSuite();
27 	typedef CppUnit::TestCaller<STXTTranslatorTest> TC;
28 
29 	suite->addTest(
30 		new TC("STXTTranslator IdentifyTest",
31 			&STXTTranslatorTest::IdentifyTest));
32 
33 	suite->addTest(
34 		new TC("STXTTranslator TranslateTest",
35 			&STXTTranslatorTest::TranslateTest));
36 
37 	suite->addTest(
38 		new TC("STXTTranslator ConfigMessageTest",
39 			&STXTTranslatorTest::ConfigMessageTest));
40 
41 #if !TEST_R5
42 	suite->addTest(
43 		new TC("STXTTranslator LoadAddOnTest",
44 			&STXTTranslatorTest::LoadAddOnTest));
45 #endif
46 
47 	return suite;
48 }
49 
50 // setUp
51 void
52 STXTTranslatorTest::setUp()
53 {
54 	BTestCase::setUp();
55 }
56 
57 // tearDown
58 void
59 STXTTranslatorTest::tearDown()
60 {
61 	BTestCase::tearDown();
62 }
63 
64 void
65 CheckStyled(translator_info *pti)
66 {
67 	CheckTranslatorInfo(pti, B_STYLED_TEXT_FORMAT, B_TRANSLATOR_TEXT,
68 		0.5f, 0.5f, "Be styled text file", "text/x-vnd.Be-stxt");
69 }
70 
71 void
72 CheckPlain(translator_info *pti)
73 {
74 	CheckTranslatorInfo(pti, B_TRANSLATOR_TEXT, B_TRANSLATOR_TEXT,
75 		0.4f, 0.6f, "Plain text file", "text/plain");
76 }
77 
78 void
79 IdentifyTests(STXTTranslatorTest *ptest, BTranslatorRoster *proster,
80 	const char **paths, int32 len, bool bplain)
81 {
82 	translator_info ti;
83 	printf(" [%d] ", (int) bplain);
84 
85 	for (int32 i = 0; i < len; i++) {
86 		ptest->NextSubTest();
87 		BFile file;
88 		printf(" [%s] ", paths[i]);
89 		CPPUNIT_ASSERT(file.SetTo(paths[i], B_READ_ONLY) == B_OK);
90 
91 		// Identify (output: B_TRANSLATOR_ANY_TYPE)
92 		ptest->NextSubTest();
93 		memset(&ti, 0, sizeof(translator_info));
94 		CPPUNIT_ASSERT(proster->Identify(&file, NULL, &ti) == B_OK);
95 		if (bplain)
96 			CheckPlain(&ti);
97 		else
98 			CheckStyled(&ti);
99 
100 		// Identify (output: B_TRANSLATOR_TEXT)
101 		ptest->NextSubTest();
102 		memset(&ti, 0, sizeof(translator_info));
103 		CPPUNIT_ASSERT(proster->Identify(&file, NULL, &ti, 0, NULL,
104 			B_TRANSLATOR_TEXT) == B_OK);
105 		if (bplain)
106 			CheckPlain(&ti);
107 		else
108 			CheckStyled(&ti);
109 
110 		// Identify (output: B_STYLED_TEXT_FORMAT)
111 		ptest->NextSubTest();
112 		memset(&ti, 0, sizeof(translator_info));
113 		CPPUNIT_ASSERT(proster->Identify(&file, NULL, &ti, 0, NULL,
114 			B_STYLED_TEXT_FORMAT) == B_OK);
115 		if (bplain)
116 			CheckPlain(&ti);
117 		else
118 			CheckStyled(&ti);
119 	}
120 }
121 
122 void
123 STXTTranslatorTest::IdentifyTest()
124 {
125 	// Init
126 	NextSubTest();
127 	status_t result = B_ERROR;
128 	BTranslatorRoster *proster = new BTranslatorRoster();
129 	CPPUNIT_ASSERT(proster);
130 	CPPUNIT_ASSERT(proster->AddTranslators(
131 		"/boot/home/config/add-ons/Translators/STXTTranslator") == B_OK);
132 	BFile wronginput("../src/tests/kits/translation/data/images/image.jpg",
133 		B_READ_ONLY);
134 	CPPUNIT_ASSERT(wronginput.InitCheck() == B_OK);
135 
136 	// Identify (bad input, output types)
137 	NextSubTest();
138 	translator_info ti;
139 	memset(&ti, 0, sizeof(translator_info));
140 	result = proster->Identify(&wronginput, NULL, &ti, 0,
141 		NULL, B_TRANSLATOR_BITMAP);
142 	CPPUNIT_ASSERT(result == B_NO_TRANSLATOR);
143 	CPPUNIT_ASSERT(ti.type == 0 && ti.translator == 0);
144 
145 	// Identify (wrong type of input data)
146 	NextSubTest();
147 	memset(&ti, 0, sizeof(translator_info));
148 	result = proster->Identify(&wronginput, NULL, &ti);
149 	CPPUNIT_ASSERT(result == B_OK);
150 	CheckTranslatorInfo(&ti, B_TRANSLATOR_TEXT, B_TRANSLATOR_TEXT, 0.4f, 0.36f,
151 		"Plain text file", "text/plain");
152 
153 	// Identify (wrong magic)
154 	NextSubTest();
155 	memset(&ti, 0, sizeof(translator_info));
156 	BFile wrongmagic("../src/tests/kits/translation/data/text/wrong_magic.stxt",
157 		B_READ_ONLY);
158 	CPPUNIT_ASSERT(wrongmagic.InitCheck() == B_OK);
159 	result = proster->Identify(&wrongmagic, NULL, &ti);
160 	CPPUNIT_ASSERT(result == B_OK);
161 	CheckTranslatorInfo(&ti, B_TRANSLATOR_TEXT, B_TRANSLATOR_TEXT, 0.4f, 0.36f,
162 		"Plain text file", "text/plain");
163 
164 	// Identify (wrong version)
165 	NextSubTest();
166 	memset(&ti, 0, sizeof(translator_info));
167 	BFile wrongversion("../src/tests/kits/translation/data/text/wrong_version.stxt",
168 		B_READ_ONLY);
169 	CPPUNIT_ASSERT(wrongversion.InitCheck() == B_OK);
170 	result = proster->Identify(&wrongversion, NULL, &ti);
171 	CPPUNIT_ASSERT(result == B_OK);
172 	CheckTranslatorInfo(&ti, B_TRANSLATOR_TEXT, B_TRANSLATOR_TEXT, 0.4f, 0.36f,
173 		"Plain text file", "text/plain");
174 
175 	const char *aPlainFiles[] = {
176 		"../src/tests/kits/translation/data/text/ascii.txt",
177 		"../src/tests/kits/translation/data/text/japanese.txt",
178 		"../src/tests/kits/translation/data/text/multi_byte.txt",
179 		"../src/tests/kits/translation/data/text/one_length.txt",
180 		"../src/tests/kits/translation/data/text/sentence.txt",
181 		"../src/tests/kits/translation/data/text/symbols.txt",
182 		"../src/tests/kits/translation/data/text/zero_length.txt"
183 	};
184 	const char *aStyledFiles[] = {
185 		"../src/tests/kits/translation/data/text/ascii.stxt",
186 		"../src/tests/kits/translation/data/text/japanese.stxt",
187 		"../src/tests/kits/translation/data/text/multi_byte.stxt",
188 		"../src/tests/kits/translation/data/text/one_length.stxt",
189 		"../src/tests/kits/translation/data/text/sentence.stxt",
190 		"../src/tests/kits/translation/data/text/symbols.stxt",
191 		"../src/tests/kits/translation/data/text/zero_length.stxt",
192 	};
193 	IdentifyTests(this, proster, aPlainFiles,
194 		sizeof(aPlainFiles) / sizeof(const char *), true);
195 	IdentifyTests(this, proster, aStyledFiles,
196 		sizeof(aStyledFiles) / sizeof(const char *), false);
197 }
198 
199 void
200 TranslateTests(STXTTranslatorTest *ptest, BTranslatorRoster *proster,
201 	const char **paths, int32 len, bool bplain)
202 {
203 	int32 nlongest = 0, ncurrent = 0;
204 	// find the length of the longest string
205 	for (int32 i = 0; i < len; i++) {
206 		ncurrent = strlen(paths[i]);
207 		if (ncurrent > nlongest)
208 			nlongest = ncurrent;
209 	}
210 
211 	char *styled_path = NULL, *plain_path = NULL;
212 	styled_path = new char[nlongest + 6];
213 	plain_path = new char[nlongest + 6];
214 
215 	// Perform translations on every file in the array
216 	for (int32 i = 0; i < len; i++) {
217 		strcpy(styled_path, paths[i]);
218 		strcat(styled_path, ".stxt");
219 		strcpy(plain_path, paths[i]);
220 		strcat(plain_path, ".txt");
221 
222 		// Setup input files
223 		ptest->NextSubTest();
224 		BFile styled_file, plain_file, *pinput_file;
225 		CPPUNIT_ASSERT(styled_file.SetTo(styled_path, B_READ_ONLY) == B_OK);
226 		CPPUNIT_ASSERT(plain_file.SetTo(plain_path, B_READ_ONLY) == B_OK);
227 		if (bplain) {
228 			printf(" [%s] ", plain_path);
229 			pinput_file = &plain_file;
230 		} else {
231 			printf(" [%s] ", styled_path);
232 			pinput_file = &styled_file;
233 		}
234 
235 		BMallocIO mallio, dmallio;
236 
237 		// Convert to B_TRANSLATOR_ANY_TYPE (should be B_TRANSLATOR_TEXT)
238 		ptest->NextSubTest();
239 		CPPUNIT_ASSERT(mallio.Seek(0, SEEK_SET) == 0);
240 		CPPUNIT_ASSERT(mallio.SetSize(0) == B_OK);
241 		CPPUNIT_ASSERT(proster->Translate(pinput_file, NULL, NULL, &mallio,
242 			B_TRANSLATOR_ANY_TYPE) == B_OK);
243 		CPPUNIT_ASSERT(CompareStreams(mallio, plain_file) == true);
244 
245 		// Convert to B_TRANSLATOR_TEXT
246 		ptest->NextSubTest();
247 		CPPUNIT_ASSERT(mallio.Seek(0, SEEK_SET) == 0);
248 		CPPUNIT_ASSERT(mallio.SetSize(0) == B_OK);
249 		CPPUNIT_ASSERT(proster->Translate(pinput_file, NULL, NULL, &mallio,
250 			B_TRANSLATOR_TEXT) == B_OK);
251 		CPPUNIT_ASSERT(CompareStreams(mallio, plain_file) == true);
252 
253 		// Convert plain mallio to B_TRANSLATOR_TEXT dmallio
254 		ptest->NextSubTest();
255 		CPPUNIT_ASSERT(dmallio.Seek(0, SEEK_SET) == 0);
256 		CPPUNIT_ASSERT(dmallio.SetSize(0) == B_OK);
257 		CPPUNIT_ASSERT(proster->Translate(&mallio, NULL, NULL, &dmallio,
258 			B_TRANSLATOR_TEXT) == B_OK);
259 		CPPUNIT_ASSERT(CompareStreams(dmallio, plain_file) == true);
260 
261 		// Convert to B_STYLED_TEXT_FORMAT
262 		ptest->NextSubTest();
263 		CPPUNIT_ASSERT(mallio.Seek(0, SEEK_SET) == 0);
264 		CPPUNIT_ASSERT(mallio.SetSize(0) == B_OK);
265 		CPPUNIT_ASSERT(proster->Translate(pinput_file, NULL, NULL, &mallio,
266 			B_STYLED_TEXT_FORMAT) == B_OK);
267 		CPPUNIT_ASSERT(CompareStreams(mallio, styled_file) == true);
268 
269 		// Convert styled mallio to B_TRANSLATOR_TEXT dmallio
270 		ptest->NextSubTest();
271 		CPPUNIT_ASSERT(dmallio.Seek(0, SEEK_SET) == 0);
272 		CPPUNIT_ASSERT(dmallio.SetSize(0) == B_OK);
273 		CPPUNIT_ASSERT(proster->Translate(&mallio, NULL, NULL, &dmallio,
274 			B_TRANSLATOR_TEXT) == B_OK);
275 		CPPUNIT_ASSERT(CompareStreams(dmallio, plain_file) == true);
276 
277 		// Convert styled mallio to B_STYLED_TEXT_FORMAT dmallio
278 		ptest->NextSubTest();
279 		CPPUNIT_ASSERT(dmallio.Seek(0, SEEK_SET) == 0);
280 		CPPUNIT_ASSERT(dmallio.SetSize(0) == B_OK);
281 		CPPUNIT_ASSERT(proster->Translate(&mallio, NULL, NULL, &dmallio,
282 			B_STYLED_TEXT_FORMAT) == B_OK);
283 		CPPUNIT_ASSERT(CompareStreams(dmallio, styled_file) == true);
284 	}
285 
286 	delete[] styled_path;
287 	styled_path = NULL;
288 	delete[] plain_path;
289 	plain_path = NULL;
290 }
291 
292 void
293 STXTTranslatorTest::TranslateTest()
294 {
295 	// Init
296 	NextSubTest();
297 	status_t result = B_ERROR;
298 	off_t filesize = -1;
299 	BTranslatorRoster *proster = new BTranslatorRoster();
300 	CPPUNIT_ASSERT(proster);
301 	CPPUNIT_ASSERT(proster->AddTranslators(
302 		"/boot/home/config/add-ons/Translators/STXTTranslator") == B_OK);
303 	BFile wronginput("../src/tests/kits/translation/data/images/image.jpg",
304 		B_READ_ONLY);
305 	CPPUNIT_ASSERT(wronginput.InitCheck() == B_OK);
306 	BFile output("/tmp/stxt_test.out", B_READ_WRITE |
307 		B_CREATE_FILE | B_ERASE_FILE);
308 	CPPUNIT_ASSERT(output.InitCheck() == B_OK);
309 
310 	// Translate (bad input, output types)
311 	NextSubTest();
312 	result = proster->Translate(&wronginput, NULL, NULL, &output,
313 		B_TRANSLATOR_BITMAP);
314 	CPPUNIT_ASSERT(result == B_NO_TRANSLATOR);
315 	CPPUNIT_ASSERT(output.GetSize(&filesize) == B_OK);
316 	CPPUNIT_ASSERT(filesize == 0);
317 
318 	// Translate (wrong type of input data)
319 	NextSubTest();
320 	result = proster->Translate(&wronginput, NULL, NULL, &output,
321 		B_TRANSLATOR_TEXT);
322 	CPPUNIT_ASSERT(result == B_OK);
323 	CPPUNIT_ASSERT(CompareStreams(wronginput, output) == true);
324 
325 	// Translate (wrong type of input, B_TRANSLATOR_ANY_TYPE output)
326 	NextSubTest();
327 	CPPUNIT_ASSERT(output.Seek(0, SEEK_SET) == 0);
328 	CPPUNIT_ASSERT(output.SetSize(0) == B_OK);
329 	result = proster->Translate(&wronginput, NULL, NULL, &output,
330 		B_TRANSLATOR_ANY_TYPE);
331 	CPPUNIT_ASSERT(result == B_OK);
332 	CPPUNIT_ASSERT(CompareStreams(wronginput, output) == true);
333 
334 	// Translate (wrong magic)
335 	NextSubTest();
336 	CPPUNIT_ASSERT(output.Seek(0, SEEK_SET) == 0);
337 	CPPUNIT_ASSERT(output.SetSize(0) == B_OK);
338 	BFile wrongmagic("../src/tests/kits/translation/data/text/wrong_magic.stxt",
339 		B_READ_ONLY);
340 	CPPUNIT_ASSERT(wrongmagic.InitCheck() == B_OK);
341 	result = proster->Translate(&wrongmagic, NULL, NULL, &output,
342 		B_TRANSLATOR_ANY_TYPE);
343 	CPPUNIT_ASSERT(result == B_OK);
344 	CPPUNIT_ASSERT(CompareStreams(wrongmagic, output) == true);
345 
346 	// Translate (wrong version)
347 	NextSubTest();
348 	CPPUNIT_ASSERT(output.Seek(0, SEEK_SET) == 0);
349 	CPPUNIT_ASSERT(output.SetSize(0) == B_OK);
350 	BFile wrongversion("../src/tests/kits/translation/data/text/wrong_version.stxt",
351 		B_READ_ONLY);
352 	CPPUNIT_ASSERT(wrongversion.InitCheck() == B_OK);
353 	result = proster->Translate(&wrongversion, NULL, NULL, &output,
354 		B_TRANSLATOR_ANY_TYPE);
355 	CPPUNIT_ASSERT(result == B_OK);
356 	CPPUNIT_ASSERT(CompareStreams(wrongversion, output) == true);
357 
358 	// Translate various data
359 	const char *aPlainTextFiles[] = {
360 		"../src/tests/kits/translation/data/text/ascii",
361 		"../src/tests/kits/translation/data/text/japanese",
362 		"../src/tests/kits/translation/data/text/multi_byte",
363 		"../src/tests/kits/translation/data/text/one_length",
364 		"../src/tests/kits/translation/data/text/symbols",
365 		"../src/tests/kits/translation/data/text/zero_length"
366 	};
367 	const char *aStyledTextFiles[] = {
368 		"../src/tests/kits/translation/data/text/ascii",
369 		"../src/tests/kits/translation/data/text/japanese",
370 		"../src/tests/kits/translation/data/text/multi_byte",
371 		"../src/tests/kits/translation/data/text/one_length",
372 		"../src/tests/kits/translation/data/text/sentence",
373 		"../src/tests/kits/translation/data/text/symbols",
374 		"../src/tests/kits/translation/data/text/zero_length"
375 	};
376 	TranslateTests(this, proster, aPlainTextFiles,
377 		sizeof(aPlainTextFiles) / sizeof(const char *), true);
378 	TranslateTests(this, proster, aStyledTextFiles,
379 		sizeof(aStyledTextFiles) / sizeof(const char *), false);
380 }
381 
382 // Make certain that the STXTTranslator does not
383 // provide a configuration message
384 void
385 STXTTranslatorTest::ConfigMessageTest()
386 {
387 	// Init
388 	NextSubTest();
389 	BTranslatorRoster *proster = new BTranslatorRoster();
390 	CPPUNIT_ASSERT(proster);
391 	CPPUNIT_ASSERT(proster->AddTranslators(
392 		"/boot/home/config/add-ons/Translators/STXTTranslator") == B_OK);
393 
394 	// GetAllTranslators
395 	NextSubTest();
396 	translator_id tid, *pids = NULL;
397 	int32 count = 0;
398 	CPPUNIT_ASSERT(proster->GetAllTranslators(&pids, &count) == B_OK);
399 	CPPUNIT_ASSERT(pids);
400 	CPPUNIT_ASSERT(count == 1);
401 	tid = pids[0];
402 	delete[] pids;
403 	pids = NULL;
404 
405 	// GetConfigurationMessage
406 	NextSubTest();
407 	BMessage msg;
408 	CPPUNIT_ASSERT(proster->GetConfigurationMessage(tid, &msg) == B_OK);
409 	CPPUNIT_ASSERT(!msg.IsEmpty());
410 
411 	// B_TRANSLATOR_EXT_HEADER_ONLY
412 	NextSubTest();
413 	bool bheaderonly = true;
414 	CPPUNIT_ASSERT(
415 		msg.FindBool(B_TRANSLATOR_EXT_HEADER_ONLY, &bheaderonly) == B_OK);
416 	CPPUNIT_ASSERT(bheaderonly == false);
417 
418 	// B_TRANSLATOR_EXT_DATA_ONLY
419 	NextSubTest();
420 	bool bdataonly = true;
421 	CPPUNIT_ASSERT(
422 		msg.FindBool(B_TRANSLATOR_EXT_DATA_ONLY, &bdataonly) == B_OK);
423 	CPPUNIT_ASSERT(bdataonly == false);
424 }
425 
426 #if !TEST_R5
427 
428 // The input formats that this translator is supposed to support
429 translation_format gSTXTInputFormats[] = {
430 	{
431 		B_TRANSLATOR_TEXT,
432 		B_TRANSLATOR_TEXT,
433 		0.4f, // quality
434 		0.6f, // capability
435 		"text/plain",
436 		"Plain text file"
437 	},
438 	{
439 		B_STYLED_TEXT_FORMAT,
440 		B_TRANSLATOR_TEXT,
441 		0.5f,
442 		0.5f,
443 		"text/x-vnd.Be-stxt",
444 		"Be styled text file"
445 	}
446 };
447 
448 // The output formats that this translator is supposed to support
449 translation_format gSTXTOutputFormats[] = {
450 	{
451 		B_TRANSLATOR_TEXT,
452 		B_TRANSLATOR_TEXT,
453 		0.4f, // quality
454 		0.6f, // capability
455 		"text/plain",
456 		"Plain text file"
457 	},
458 	{
459 		B_STYLED_TEXT_FORMAT,
460 		B_TRANSLATOR_TEXT,
461 		0.5f,
462 		0.5f,
463 		"text/x-vnd.Be-stxt",
464 		"Be styled text file"
465 	}
466 };
467 
468 void
469 STXTTranslatorTest::LoadAddOnTest()
470 {
471 	TranslatorLoadAddOnTest("/boot/home/config/add-ons/Translators/STXTTranslator",
472 		this,
473 		gSTXTInputFormats, sizeof(gSTXTInputFormats) / sizeof(translation_format),
474 		gSTXTOutputFormats, sizeof(gSTXTOutputFormats) / sizeof(translation_format),
475 		B_TRANSLATION_MAKE_VERSION(1,0,0));
476 }
477 
478 #endif // #if !TEST_R5
479