xref: /haiku/src/tests/add-ons/translators/stxttranslator/STXTTranslatorTest.cpp (revision 9642f7705b27e5c270c15fa526d14e1848c2c27d)
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 	BFile styled_file, plain_file;
216 
217 	// Perform translations on every file in the array
218 	for (int32 i = 0; i < len; i++) {
219 		strcpy(styled_path, paths[i]);
220 		strcat(styled_path, ".stxt");
221 		strcpy(plain_path, paths[i]);
222 		strcat(plain_path, ".txt");
223 
224 		// Setup input files
225 		ptest->NextSubTest();
226 		CPPUNIT_ASSERT(styled_file.SetTo(styled_path, B_READ_ONLY) == B_OK);
227 		CPPUNIT_ASSERT(plain_file.SetTo(plain_path, B_READ_ONLY) == B_OK);
228 
229 		BFile *pinput_file;
230 		if (bplain) {
231 			printf(" [%s] ", plain_path);
232 			pinput_file = &plain_file;
233 		} else {
234 			printf(" [%s] ", styled_path);
235 			pinput_file = &styled_file;
236 		}
237 
238 		BMallocIO mallio, dmallio;
239 
240 		// Convert to B_TRANSLATOR_ANY_TYPE (should be B_TRANSLATOR_TEXT)
241 		ptest->NextSubTest();
242 		CPPUNIT_ASSERT(mallio.Seek(0, SEEK_SET) == 0);
243 		CPPUNIT_ASSERT(mallio.SetSize(0) == B_OK);
244 		CPPUNIT_ASSERT(proster->Translate(pinput_file, NULL, NULL, &mallio,
245 			B_TRANSLATOR_ANY_TYPE) == B_OK);
246 		CPPUNIT_ASSERT(CompareStreams(mallio, plain_file) == true);
247 
248 		// Convert to B_TRANSLATOR_TEXT
249 		ptest->NextSubTest();
250 		CPPUNIT_ASSERT(mallio.Seek(0, SEEK_SET) == 0);
251 		CPPUNIT_ASSERT(mallio.SetSize(0) == B_OK);
252 		CPPUNIT_ASSERT(proster->Translate(pinput_file, NULL, NULL, &mallio,
253 			B_TRANSLATOR_TEXT) == B_OK);
254 		CPPUNIT_ASSERT(CompareStreams(mallio, plain_file) == true);
255 
256 		// Convert plain mallio to B_TRANSLATOR_TEXT dmallio
257 		ptest->NextSubTest();
258 		CPPUNIT_ASSERT(dmallio.Seek(0, SEEK_SET) == 0);
259 		CPPUNIT_ASSERT(dmallio.SetSize(0) == B_OK);
260 		CPPUNIT_ASSERT(proster->Translate(&mallio, NULL, NULL, &dmallio,
261 			B_TRANSLATOR_TEXT) == B_OK);
262 		CPPUNIT_ASSERT(CompareStreams(dmallio, plain_file) == true);
263 
264 		// Convert to B_STYLED_TEXT_FORMAT
265 		ptest->NextSubTest();
266 		CPPUNIT_ASSERT(mallio.Seek(0, SEEK_SET) == 0);
267 		CPPUNIT_ASSERT(mallio.SetSize(0) == B_OK);
268 		CPPUNIT_ASSERT(proster->Translate(pinput_file, NULL, NULL, &mallio,
269 			B_STYLED_TEXT_FORMAT) == B_OK);
270 		CPPUNIT_ASSERT(CompareStreams(mallio, styled_file) == true);
271 
272 		// Convert styled mallio to B_TRANSLATOR_TEXT dmallio
273 		ptest->NextSubTest();
274 		CPPUNIT_ASSERT(dmallio.Seek(0, SEEK_SET) == 0);
275 		CPPUNIT_ASSERT(dmallio.SetSize(0) == B_OK);
276 		CPPUNIT_ASSERT(proster->Translate(&mallio, NULL, NULL, &dmallio,
277 			B_TRANSLATOR_TEXT) == B_OK);
278 		CPPUNIT_ASSERT(CompareStreams(dmallio, plain_file) == true);
279 
280 		// Convert styled mallio to B_STYLED_TEXT_FORMAT dmallio
281 		ptest->NextSubTest();
282 		CPPUNIT_ASSERT(dmallio.Seek(0, SEEK_SET) == 0);
283 		CPPUNIT_ASSERT(dmallio.SetSize(0) == B_OK);
284 		CPPUNIT_ASSERT(proster->Translate(&mallio, NULL, NULL, &dmallio,
285 			B_STYLED_TEXT_FORMAT) == B_OK);
286 		CPPUNIT_ASSERT(CompareStreams(dmallio, styled_file) == true);
287 	}
288 
289 	delete[] styled_path;
290 	styled_path = NULL;
291 	delete[] plain_path;
292 	plain_path = NULL;
293 }
294 
295 void
296 STXTTranslatorTest::TranslateTest()
297 {
298 	// Init
299 	NextSubTest();
300 	status_t result = B_ERROR;
301 	off_t filesize = -1;
302 	BTranslatorRoster *proster = new BTranslatorRoster();
303 	CPPUNIT_ASSERT(proster);
304 	CPPUNIT_ASSERT(proster->AddTranslators(
305 		"/boot/home/config/add-ons/Translators/STXTTranslator") == B_OK);
306 	BFile wronginput("../src/tests/kits/translation/data/images/image.jpg",
307 		B_READ_ONLY);
308 	CPPUNIT_ASSERT(wronginput.InitCheck() == B_OK);
309 	BFile output("/tmp/stxt_test.out", B_READ_WRITE |
310 		B_CREATE_FILE | B_ERASE_FILE);
311 	CPPUNIT_ASSERT(output.InitCheck() == B_OK);
312 
313 	// Translate (bad input, output types)
314 	NextSubTest();
315 	result = proster->Translate(&wronginput, NULL, NULL, &output,
316 		B_TRANSLATOR_BITMAP);
317 	CPPUNIT_ASSERT(result == B_NO_TRANSLATOR);
318 	CPPUNIT_ASSERT(output.GetSize(&filesize) == B_OK);
319 	CPPUNIT_ASSERT(filesize == 0);
320 
321 	// Translate (wrong type of input data)
322 	NextSubTest();
323 	result = proster->Translate(&wronginput, NULL, NULL, &output,
324 		B_TRANSLATOR_TEXT);
325 	CPPUNIT_ASSERT(result == B_OK);
326 	CPPUNIT_ASSERT(CompareStreams(wronginput, output) == true);
327 
328 	// Translate (wrong type of input, B_TRANSLATOR_ANY_TYPE output)
329 	NextSubTest();
330 	CPPUNIT_ASSERT(output.Seek(0, SEEK_SET) == 0);
331 	CPPUNIT_ASSERT(output.SetSize(0) == B_OK);
332 	result = proster->Translate(&wronginput, NULL, NULL, &output,
333 		B_TRANSLATOR_ANY_TYPE);
334 	CPPUNIT_ASSERT(result == B_OK);
335 	CPPUNIT_ASSERT(CompareStreams(wronginput, output) == true);
336 
337 	// Translate (wrong magic)
338 	NextSubTest();
339 	CPPUNIT_ASSERT(output.Seek(0, SEEK_SET) == 0);
340 	CPPUNIT_ASSERT(output.SetSize(0) == B_OK);
341 	BFile wrongmagic("../src/tests/kits/translation/data/text/wrong_magic.stxt",
342 		B_READ_ONLY);
343 	CPPUNIT_ASSERT(wrongmagic.InitCheck() == B_OK);
344 	result = proster->Translate(&wrongmagic, NULL, NULL, &output,
345 		B_TRANSLATOR_ANY_TYPE);
346 	CPPUNIT_ASSERT(result == B_OK);
347 	CPPUNIT_ASSERT(CompareStreams(wrongmagic, output) == true);
348 
349 	// Translate (wrong version)
350 	NextSubTest();
351 	CPPUNIT_ASSERT(output.Seek(0, SEEK_SET) == 0);
352 	CPPUNIT_ASSERT(output.SetSize(0) == B_OK);
353 	BFile wrongversion("../src/tests/kits/translation/data/text/wrong_version.stxt",
354 		B_READ_ONLY);
355 	CPPUNIT_ASSERT(wrongversion.InitCheck() == B_OK);
356 	result = proster->Translate(&wrongversion, NULL, NULL, &output,
357 		B_TRANSLATOR_ANY_TYPE);
358 	CPPUNIT_ASSERT(result == B_OK);
359 	CPPUNIT_ASSERT(CompareStreams(wrongversion, output) == true);
360 
361 	// Translate various data
362 	const char *aPlainTextFiles[] = {
363 		"../src/tests/kits/translation/data/text/ascii",
364 		"../src/tests/kits/translation/data/text/japanese",
365 		"../src/tests/kits/translation/data/text/multi_byte",
366 		"../src/tests/kits/translation/data/text/one_length",
367 		"../src/tests/kits/translation/data/text/symbols",
368 		"../src/tests/kits/translation/data/text/zero_length"
369 	};
370 	const char *aStyledTextFiles[] = {
371 		"../src/tests/kits/translation/data/text/ascii",
372 		"../src/tests/kits/translation/data/text/japanese",
373 		"../src/tests/kits/translation/data/text/multi_byte",
374 		"../src/tests/kits/translation/data/text/one_length",
375 		"../src/tests/kits/translation/data/text/sentence",
376 		"../src/tests/kits/translation/data/text/symbols",
377 		"../src/tests/kits/translation/data/text/zero_length"
378 	};
379 	TranslateTests(this, proster, aPlainTextFiles,
380 		sizeof(aPlainTextFiles) / sizeof(const char *), true);
381 	TranslateTests(this, proster, aStyledTextFiles,
382 		sizeof(aStyledTextFiles) / sizeof(const char *), false);
383 }
384 
385 // Make certain that the STXTTranslator does not
386 // provide a configuration message
387 void
388 STXTTranslatorTest::ConfigMessageTest()
389 {
390 	// Init
391 	NextSubTest();
392 	BTranslatorRoster *proster = new BTranslatorRoster();
393 	CPPUNIT_ASSERT(proster);
394 	CPPUNIT_ASSERT(proster->AddTranslators(
395 		"/boot/home/config/add-ons/Translators/STXTTranslator") == B_OK);
396 
397 	// GetAllTranslators
398 	NextSubTest();
399 	translator_id tid, *pids = NULL;
400 	int32 count = 0;
401 	CPPUNIT_ASSERT(proster->GetAllTranslators(&pids, &count) == B_OK);
402 	CPPUNIT_ASSERT(pids);
403 	CPPUNIT_ASSERT(count == 1);
404 	tid = pids[0];
405 	delete[] pids;
406 	pids = NULL;
407 
408 	// GetConfigurationMessage
409 	NextSubTest();
410 	BMessage msg;
411 	CPPUNIT_ASSERT(proster->GetConfigurationMessage(tid, &msg) == B_OK);
412 	CPPUNIT_ASSERT(!msg.IsEmpty());
413 
414 	// B_TRANSLATOR_EXT_HEADER_ONLY
415 	NextSubTest();
416 	bool bheaderonly = true;
417 	CPPUNIT_ASSERT(
418 		msg.FindBool(B_TRANSLATOR_EXT_HEADER_ONLY, &bheaderonly) == B_OK);
419 	CPPUNIT_ASSERT(bheaderonly == false);
420 
421 	// B_TRANSLATOR_EXT_DATA_ONLY
422 	NextSubTest();
423 	bool bdataonly = true;
424 	CPPUNIT_ASSERT(
425 		msg.FindBool(B_TRANSLATOR_EXT_DATA_ONLY, &bdataonly) == B_OK);
426 	CPPUNIT_ASSERT(bdataonly == false);
427 }
428 
429 #if !TEST_R5
430 
431 // The input formats that this translator is supposed to support
432 translation_format gSTXTInputFormats[] = {
433 	{
434 		B_TRANSLATOR_TEXT,
435 		B_TRANSLATOR_TEXT,
436 		0.4f, // quality
437 		0.6f, // capability
438 		"text/plain",
439 		"Plain text file"
440 	},
441 	{
442 		B_STYLED_TEXT_FORMAT,
443 		B_TRANSLATOR_TEXT,
444 		0.5f,
445 		0.5f,
446 		"text/x-vnd.Be-stxt",
447 		"Be styled text file"
448 	}
449 };
450 
451 // The output formats that this translator is supposed to support
452 translation_format gSTXTOutputFormats[] = {
453 	{
454 		B_TRANSLATOR_TEXT,
455 		B_TRANSLATOR_TEXT,
456 		0.4f, // quality
457 		0.6f, // capability
458 		"text/plain",
459 		"Plain text file"
460 	},
461 	{
462 		B_STYLED_TEXT_FORMAT,
463 		B_TRANSLATOR_TEXT,
464 		0.5f,
465 		0.5f,
466 		"text/x-vnd.Be-stxt",
467 		"Be styled text file"
468 	}
469 };
470 
471 void
472 STXTTranslatorTest::LoadAddOnTest()
473 {
474 	TranslatorLoadAddOnTest("/boot/home/config/add-ons/Translators/STXTTranslator",
475 		this,
476 		gSTXTInputFormats, sizeof(gSTXTInputFormats) / sizeof(translation_format),
477 		gSTXTOutputFormats, sizeof(gSTXTOutputFormats) / sizeof(translation_format),
478 		B_TRANSLATION_MAKE_VERSION(1,0,0));
479 }
480 
481 #endif // #if !TEST_R5
482