1 /************************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 2000-2009, International Business Machines Corporation
4 * and others. All Rights Reserved.
5 ************************************************************************/
6 /************************************************************************
7 * Date Name Description
8 * 1/03/2000 Madhu Creation.
9 ************************************************************************/
10
11 #include "unicode/utypes.h"
12
13 #if !UCONFIG_NO_TRANSLITERATION
14
15 #include "ittrans.h"
16 #include "transapi.h"
17 #include "unicode/utypes.h"
18 #include "unicode/translit.h"
19 #include "unicode/unifilt.h"
20 #include "cpdtrans.h"
21 #include <string.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include "unicode/rep.h"
25 #include "unicode/locid.h"
26 #include "unicode/uniset.h"
27
getInt(UnicodeString str)28 int32_t getInt(UnicodeString str)
29 {
30 char buffer[20];
31 int len=str.length();
32 if(len>=20) {
33 len=19;
34 }
35 str.extract(0, len, buffer, "");
36 buffer[len]=0;
37 return atoi(buffer);
38 }
39
40 //---------------------------------------------
41 // runIndexedTest
42 //---------------------------------------------
43
44 void
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)45 TransliteratorAPITest::runIndexedTest(int32_t index, UBool exec,
46 const char* &name, char* /*par*/) {
47 switch (index) {
48 TESTCASE(0,TestgetInverse);
49 TESTCASE(1,TestgetID);
50 TESTCASE(2,TestGetDisplayName);
51 TESTCASE(3,TestTransliterate1);
52 TESTCASE(4,TestTransliterate2);
53 TESTCASE(5,TestTransliterate3);
54 TESTCASE(6,TestSimpleKeyboardTransliterator);
55 TESTCASE(7,TestKeyboardTransliterator1);
56 TESTCASE(8,TestKeyboardTransliterator2);
57 TESTCASE(9,TestKeyboardTransliterator3);
58 TESTCASE(10,TestGetAdoptFilter);
59 TESTCASE(11,TestClone);
60 TESTCASE(12,TestNullTransliterator);
61 TESTCASE(13,TestRegisterUnregister);
62 TESTCASE(14,TestUnicodeFunctor);
63 default: name = ""; break;
64 }
65 }
66
67
TestgetID()68 void TransliteratorAPITest::TestgetID() {
69 UnicodeString trans="Latin-Greek";
70 UnicodeString ID;
71 UParseError parseError;
72 UErrorCode status = U_ZERO_ERROR;
73 Transliterator* t= Transliterator::createInstance(trans, UTRANS_FORWARD, parseError, status);
74 if(t==0 || U_FAILURE(status)){
75 dataerrln("FAIL: construction of Latin-Greek - %s",u_errorName(status));
76 return;
77 }else{
78 ID= t->getID();
79 if(ID != trans)
80 errln("FAIL: getID returned " + ID + " instead of Latin-Greek");
81 delete t;
82 }
83 int i;
84 for (i=0; i<Transliterator::countAvailableIDs(); i++){
85 status = U_ZERO_ERROR;
86 ID = (UnicodeString) Transliterator::getAvailableID(i);
87 if(ID.indexOf("Thai")>-1){
88 continue;
89 }
90 t = Transliterator::createInstance(ID, UTRANS_FORWARD, parseError, status);
91 if(t == 0){
92 errln("FAIL: " + ID);
93 continue;
94 }
95 if(ID != t->getID())
96 errln("FAIL: getID() returned " + t->getID() + " instead of " + ID);
97 delete t;
98 }
99 ID=(UnicodeString)Transliterator::getAvailableID(i);
100 if(ID != (UnicodeString)Transliterator::getAvailableID(0)){
101 errln("FAIL: calling getAvailableID(index > coundAvailableIDs) should make index=0\n");
102 }
103
104 Transliterator* t1=Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseError, status);
105 Transliterator* t2=Transliterator::createInstance("Latin-Greek", UTRANS_FORWARD, parseError, status);
106 if(t1 ==0 || t2 == 0){
107 errln("FAIL: construction");
108 return;
109 }
110 Transliterator* t3=t1->clone();
111 Transliterator* t4=t2->clone();
112
113 if(t1->getID() != t3->getID() || t2->getID() != t4->getID() ||
114 t1->getID() == t4->getID() || t2->getID() == t3->getID() ||
115 t1->getID()== t4->getID() )
116 errln("FAIL: getID or clone failed");
117
118
119 Transliterator* t5=Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseError, status);
120 if(t5 == 0)
121 errln("FAIL: construction");
122 else if(t1->getID() != t5->getID() || t5->getID() != t3->getID() || t1->getID() != t3->getID())
123 errln("FAIL: getID or clone failed");
124
125
126 delete t1;
127 delete t2;
128 delete t3;
129 delete t4;
130 delete t5;
131 }
132
TestgetInverse()133 void TransliteratorAPITest::TestgetInverse() {
134 UErrorCode status = U_ZERO_ERROR;
135 UParseError parseError;
136 Transliterator* t1 = Transliterator::createInstance("Katakana-Latin", UTRANS_FORWARD, parseError, status);
137 Transliterator* invt1 = Transliterator::createInstance("Latin-Katakana", UTRANS_FORWARD, parseError, status);
138 Transliterator* t2 = Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseError, status);
139 Transliterator* invt2 = Transliterator::createInstance("Devanagari-Latin", UTRANS_FORWARD, parseError, status);
140 if(t1 == 0 || invt1 == 0 || t2 == 0 || invt2 == 0) {
141 dataerrln("FAIL: in instantiation - %s", u_errorName(status));
142 return;
143 }
144
145 Transliterator* inverse1=t1->createInverse(status);
146 Transliterator* inverse2=t2->createInverse(status);
147 if(inverse1->getID() != invt1->getID() || inverse2->getID() != invt2->getID()
148 || inverse1->getID() == invt2->getID() || inverse2->getID() == invt1->getID() )
149 errln("FAIL: getInverse() ");
150
151 UnicodeString TransID[]={
152 "Halfwidth-Fullwidth",
153 "Fullwidth-Halfwidth",
154 "Greek-Latin" ,
155 "Latin-Greek",
156 //"Arabic-Latin", // removed in 2.0
157 //"Latin-Arabic",
158 "Katakana-Latin",
159 "Latin-Katakana",
160 //"Hebrew-Latin", // removed in 2.0
161 //"Latin-Hebrew",
162 "Cyrillic-Latin",
163 "Latin-Cyrillic",
164 "Devanagari-Latin",
165 "Latin-Devanagari",
166 "Any-Hex",
167 "Hex-Any"
168 };
169 for(uint32_t i=0; i<sizeof(TransID)/sizeof(TransID[0]); i=i+2){
170 Transliterator *trans1=Transliterator::createInstance(TransID[i], UTRANS_FORWARD, parseError, status);
171 if(t1 == 0){
172 errln("FAIL: in instantiation for" + TransID[i]);
173 continue;
174 }
175 Transliterator *inver1=trans1->createInverse(status);
176 if(inver1->getID() != TransID[i+1] )
177 errln("FAIL :getInverse() for " + TransID[i] + " returned " + inver1->getID() + " instead of " + TransID[i+1]);
178 delete inver1;
179 delete trans1;
180 }
181 delete t1;
182 delete t2;
183 delete invt1;
184 delete invt2;
185 delete inverse1;
186 delete inverse2;
187
188 }
189
TestClone()190 void TransliteratorAPITest::TestClone(){
191 Transliterator *t1, *t2, *t3, *t4;
192 UErrorCode status = U_ZERO_ERROR;
193 UParseError parseError;
194 t1=Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseError, status);
195 t2=Transliterator::createInstance("Latin-Greek", UTRANS_FORWARD, parseError, status);
196 if(t1 == 0 || t2 == 0){
197 dataerrln("FAIL: construction - %s", u_errorName(status));
198 return;
199 }
200 t3=t1->clone();
201 t4=t2->clone();
202
203 if(t1->getID() != t3->getID() || t2->getID() != t4->getID() )
204 errln("FAIL: clone or getID failed");
205 if(t1->getID()==t4->getID() || t2->getID()==t3->getID() || t1->getID()==t4->getID())
206 errln("FAIL: clone or getID failed");
207
208 delete t1;
209 delete t2;
210 delete t3;
211 delete t4;
212
213 }
214
TestGetDisplayName()215 void TransliteratorAPITest::TestGetDisplayName() {
216 UnicodeString dispNames[]= {
217 //ID, displayName
218 //"CurlyQuotes-StraightQuotes" ,"CurlyQuotes to StraightQuotes",
219 "Any-Hex" ,"Any to Hex Escape",
220 "Halfwidth-Fullwidth" ,"Halfwidth to Fullwidth" ,
221 //"Latin-Arabic" ,"Latin to Arabic" ,
222 "Latin-Devanagari" ,"Latin to Devanagari" ,
223 "Greek-Latin" ,"Greek to Latin" ,
224 //"Arabic-Latin" ,"Arabic to Latin" ,
225 "Hex-Any" ,"Hex Escape to Any",
226 "Cyrillic-Latin" ,"Cyrillic to Latin" ,
227 "Latin-Greek" ,"Latin to Greek" ,
228 "Latin-Katakana" ,"Latin to Katakana" ,
229 //"Latin-Hebrew" ,"Latin to Hebrew" ,
230 "Katakana-Latin" ,"Katakana to Latin"
231 };
232 UnicodeString name="";
233 Transliterator* t;
234 UnicodeString message;
235 UErrorCode status = U_ZERO_ERROR;
236 UParseError parseError;
237
238 #if UCONFIG_NO_FORMATTING
239 logln("Skipping, UCONFIG_NO_FORMATTING is set\n");
240 return;
241 #else
242
243 for (uint32_t i=0; i<sizeof(dispNames)/sizeof(dispNames[0]); i=i+2 ) {
244 t = Transliterator::createInstance(dispNames[i+0], UTRANS_FORWARD, parseError, status);
245 if(t==0){
246 dataerrln("FAIL: construction: " + dispNames[i+0] + " - " + u_errorName(status));
247 status = U_ZERO_ERROR;
248 continue;
249 }
250 t->getDisplayName(t->getID(), name);
251 message="Display name for ID:" + t->getID();
252 // doTest(message, name, dispNames[i+1]); //!!! This will obviously fail for any locale other than english and its children!!!
253 name="";
254 t->getDisplayName(t->getID(), Locale::getUS(), name);
255 message.remove();
256 message.append("Display name for on english locale ID:");
257 message.append(t->getID());
258 // message="Display name for on english locale ID:" + t->getID();
259 doTest(message, name, dispNames[i+1]);
260 name="";
261
262 delete t;
263 }
264 #endif
265
266 }
267
TestTransliterate1()268 void TransliteratorAPITest::TestTransliterate1(){
269
270 UnicodeString Data[]={
271 //ID, input string, transliterated string
272 "Any-Hex", "hello", UnicodeString("\\u0068\\u0065\\u006C\\u006C\\u006F", "") ,
273 "Hex-Any", UnicodeString("\\u0068\\u0065\\u006C\\u006C\\u006F", ""), "hello" ,
274 "Latin-Devanagari",CharsToUnicodeString("bha\\u0304rata"), CharsToUnicodeString("\\u092D\\u093E\\u0930\\u0924") ,
275 "Latin-Devanagari",UnicodeString("kra ksha khra gra cra dya dhya",""), CharsToUnicodeString("\\u0915\\u094D\\u0930 \\u0915\\u094D\\u0936 \\u0916\\u094D\\u0930 \\u0917\\u094D\\u0930 \\u091a\\u094D\\u0930 \\u0926\\u094D\\u092F \\u0927\\u094D\\u092F") ,
276
277 "Devanagari-Latin", CharsToUnicodeString("\\u092D\\u093E\\u0930\\u0924"), CharsToUnicodeString("bh\\u0101rata"),
278 // "Contracted-Expanded", CharsToUnicodeString("\\u00C0\\u00C1\\u0042"), CharsToUnicodeString("\\u0041\\u0300\\u0041\\u0301\\u0042") ,
279 // "Expanded-Contracted", CharsToUnicodeString("\\u0041\\u0300\\u0041\\u0301\\u0042"), CharsToUnicodeString("\\u00C0\\u00C1\\u0042") ,
280 //"Latin-Arabic", "aap", CharsToUnicodeString("\\u0627\\u06A4") ,
281 //"Arabic-Latin", CharsToUnicodeString("\\u0627\\u06A4"), "aap"
282 };
283
284 UnicodeString gotResult;
285 UnicodeString temp;
286 UnicodeString message;
287 Transliterator* t;
288 logln("Testing transliterate");
289 UErrorCode status = U_ZERO_ERROR;
290 UParseError parseError;
291
292 for(uint32_t i=0;i<sizeof(Data)/sizeof(Data[0]); i=i+3){
293 t=Transliterator::createInstance(Data[i+0], UTRANS_FORWARD, parseError, status);
294 if(t==0){
295 dataerrln("FAIL: construction: " + Data[i+0] + " Error: " + u_errorName(status));
296 dataerrln("PreContext: " + prettify(parseError.preContext) + " PostContext: " + prettify( parseError.postContext) );
297 status = U_ZERO_ERROR;
298 continue;
299 }
300 gotResult = Data[i+1];
301 t->transliterate(gotResult);
302 message=t->getID() + "->transliterate(UnicodeString, UnicodeString) for\n\t Source:" + prettify(Data[i+1]);
303 doTest(message, gotResult, Data[i+2]);
304
305 //doubt here
306 temp=Data[i+1];
307 t->transliterate(temp);
308 message.remove();
309 message.append(t->getID());
310 message.append("->transliterate(Replaceable) for \n\tSource:");
311 message.append(Data[i][1]);
312 doTest(message, temp, Data[i+2]);
313
314 callEverything(t, __LINE__);
315 delete t;
316 }
317 }
318
TestTransliterate2()319 void TransliteratorAPITest::TestTransliterate2(){
320 //testing tranliterate(String text, int start, int limit, StringBuffer result)
321 UnicodeString Data2[]={
322 //ID, input string, start, limit, transliterated string
323 "Any-Hex", "hello! How are you?", "0", "5", UnicodeString("\\u0068\\u0065\\u006C\\u006C\\u006F", ""), UnicodeString("\\u0068\\u0065\\u006C\\u006C\\u006F! How are you?", "") ,
324 "Any-Hex", "hello! How are you?", "7", "12", UnicodeString("\\u0048\\u006F\\u0077\\u0020\\u0061", ""), UnicodeString("hello! \\u0048\\u006F\\u0077\\u0020\\u0061re you?", ""),
325 "Hex-Any", CharsToUnicodeString("\\u0068\\u0065\\u006C\\u006C\\u006F\\u0021\\u0020"), "0", "5", "hello", "hello! " ,
326 // "Contracted-Expanded", CharsToUnicodeString("\\u00C0\\u00C1\\u0042"), "1", "2", CharsToUnicodeString("\\u0041\\u0301"), CharsToUnicodeString("\\u00C0\\u0041\\u0301\\u0042") ,
327 "Devanagari-Latin", CharsToUnicodeString("\\u092D\\u093E\\u0930\\u0924"), "0", "1", "bha", CharsToUnicodeString("bha\\u093E\\u0930\\u0924") ,
328 "Devanagari-Latin", CharsToUnicodeString("\\u092D\\u093E\\u0930\\u0924"), "1", "2", CharsToUnicodeString("\\u0314\\u0101"), CharsToUnicodeString("\\u092D\\u0314\\u0101\\u0930\\u0924")
329
330 };
331 logln("\n Testing transliterate(String, int, int, StringBuffer)");
332 Transliterator* t;
333 UnicodeString gotResBuf;
334 UnicodeString temp;
335 int32_t start, limit;
336 UErrorCode status = U_ZERO_ERROR;
337 UParseError parseError;
338
339 for(uint32_t i=0; i<sizeof(Data2)/sizeof(Data2[0]); i=i+6){
340 t=Transliterator::createInstance(Data2[i+0], UTRANS_FORWARD, parseError, status);
341 if(t==0){
342 dataerrln("FAIL: construction: " + prettify(Data2[i+0]) + " - " + u_errorName(status));
343 continue;
344 }
345 start=getInt(Data2[i+2]);
346 limit=getInt(Data2[i+3]);
347 Data2[i+1].extractBetween(start, limit, gotResBuf);
348 t->transliterate(gotResBuf);
349 // errln("FAIL: calling transliterate on " + t->getID());
350 doTest(t->getID() + ".transliterate(UnicodeString, int32_t, int32_t, UnicodeString):(" + start + "," + limit + ") for \n\t source: " + prettify(Data2[i+1]), gotResBuf, Data2[i+4]);
351
352 temp=Data2[i+1];
353 t->transliterate(temp, start, limit);
354 doTest(t->getID() + ".transliterate(Replaceable, int32_t, int32_t, ):(" + start + "," + limit + ") for \n\t source: " + prettify(Data2[i+1]), temp, Data2[i+5]);
355 status = U_ZERO_ERROR;
356 callEverything(t, __LINE__);
357 delete t;
358 t = NULL;
359 }
360
361 status = U_ZERO_ERROR;
362 logln("\n Try calling transliterate with illegal start and limit values");
363 t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status);
364 if(U_FAILURE(status)) {
365 errln("Error creating transliterator %s", u_errorName(status));
366 delete t;
367 return;
368 }
369 gotResBuf = temp = "try start greater than limit";
370 t->transliterate(gotResBuf, 10, 5);
371 if(gotResBuf == temp) {
372 logln("OK: start greater than limit value handled correctly");
373 } else {
374 errln("FAIL: start greater than limit value returned" + gotResBuf);
375 }
376
377 callEverything(t, __LINE__);
378 delete t;
379
380 }
TestTransliterate3()381 void TransliteratorAPITest::TestTransliterate3(){
382 UnicodeString rs="This is the replaceable String";
383 UnicodeString Data[] = {
384 "0", "0", "This is the replaceable String",
385 "2", "3", UnicodeString("Th\\u0069s is the replaceable String", ""),
386 "21", "23", UnicodeString("Th\\u0069s is the repl\\u0061\\u0063eable String", ""),
387 "14", "17", UnicodeString("Th\\u0069s is t\\u0068\\u0065\\u0020repl\\u0061\\u0063eable String", ""),
388 };
389 int start, limit;
390 UnicodeString message;
391 UParseError parseError;
392 UErrorCode status = U_ZERO_ERROR;
393 Transliterator *t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status);
394 if(U_FAILURE(status)) {
395 errln("Error creating transliterator %s", u_errorName(status));
396 delete t;
397 return;
398 }
399
400 if(t == 0)
401 errln("FAIL : construction");
402 for(uint32_t i=0; i<sizeof(Data)/sizeof(Data[0]); i=i+3){
403 start=getInt(Data[i+0]);
404 limit=getInt(Data[i+1]);
405 t->transliterate(rs, start, limit);
406 message=t->getID() + ".transliterate(ReplaceableString, start, limit):("+start+","+limit+"):";
407 doTest(message, rs, Data[i+2]);
408 }
409 delete t;
410 }
411
TestSimpleKeyboardTransliterator()412 void TransliteratorAPITest::TestSimpleKeyboardTransliterator(){
413 logln("simple call to transliterate");
414 UErrorCode status=U_ZERO_ERROR;
415 UParseError parseError;
416 Transliterator* t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status);
417 if(t == 0) {
418 UnicodeString context;
419
420 if (parseError.preContext[0]) {
421 context += (UnicodeString)" at " + parseError.preContext;
422 }
423 if (parseError.postContext[0]) {
424 context += (UnicodeString)" | " + parseError.postContext;
425 }
426 errln((UnicodeString)"FAIL: can't create Any-Hex, " +
427 (UnicodeString)u_errorName(status) + context);
428 return;
429 }
430 UTransPosition index={19,20,20,20};
431 UnicodeString rs= "Transliterate this-''";
432 UnicodeString insertion="abc";
433 UnicodeString expected=UnicodeString("Transliterate this-'\\u0061\\u0062\\u0063'", "");
434 t->transliterate(rs, index, insertion, status);
435 if(U_FAILURE(status))
436 errln("FAIL: " + t->getID()+ ".translitere(Replaceable, int[], UnicodeString, UErrorCode)-->" + (UnicodeString)u_errorName(status));
437 t->finishTransliteration(rs, index);
438 UnicodeString message="transliterate";
439 doTest(message, rs, expected);
440
441 logln("try calling transliterate with invalid index values");
442 UTransPosition index1[]={
443 //START, LIMIT, CURSOR
444 {10, 10, 12, 10}, //invalid since CURSOR>LIMIT valid:-START <= CURSOR <= LIMIT
445 {17, 16, 17, 17}, //invalid since START>LIMIT valid:-0<=START<=LIMIT
446 {-1, 16, 14, 16}, //invalid since START<0
447 {3, 50, 2, 50} //invalid since LIMIT>text.length()
448 };
449 for(uint32_t i=0; i<sizeof(index1)/sizeof(index1[0]); i++){
450 status=U_ZERO_ERROR;
451 t->transliterate(rs, index1[i], insertion, status);
452 if(status == U_ILLEGAL_ARGUMENT_ERROR)
453 logln("OK: invalid index values handled correctly");
454 else
455 errln("FAIL: invalid index values didn't throw U_ILLEGAL_ARGUMENT_ERROR throw" + (UnicodeString)u_errorName(status));
456 }
457
458 delete t;
459 }
TestKeyboardTransliterator1()460 void TransliteratorAPITest::TestKeyboardTransliterator1(){
461 UnicodeString Data[]={
462 //insertion, buffer
463 "a", UnicodeString("\\u0061", "") ,
464 "bbb", UnicodeString("\\u0061\\u0062\\u0062\\u0062", "") ,
465 "ca", UnicodeString("\\u0061\\u0062\\u0062\\u0062\\u0063\\u0061", "") ,
466 " ", UnicodeString("\\u0061\\u0062\\u0062\\u0062\\u0063\\u0061\\u0020", "") ,
467 "", UnicodeString("\\u0061\\u0062\\u0062\\u0062\\u0063\\u0061\\u0020", "") ,
468
469 "a", UnicodeString("\\u0061", "") ,
470 "b", UnicodeString("\\u0061\\u0062", "") ,
471 "z", UnicodeString("\\u0061\\u0062\\u007A", "") ,
472 "", UnicodeString("\\u0061\\u0062\\u007A", "")
473
474 };
475 UParseError parseError;
476 UErrorCode status = U_ZERO_ERROR;
477 Transliterator* t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status);
478 if(U_FAILURE(status)) {
479 errln("Error creating transliterator %s", u_errorName(status));
480 delete t;
481 return;
482 }
483 //keyboardAux(t, Data);
484 UTransPosition index={0, 0, 0, 0};
485 UnicodeString s;
486 uint32_t i;
487 logln("Testing transliterate(Replaceable, int32_t, UnicodeString, UErrorCode)");
488 for (i=0; i<10; i=i+2) {
489 UnicodeString log;
490 if (Data[i+0] != "") {
491 log = s + " + " + Data[i+0] + " -> ";
492 t->transliterate(s, index, Data[i+0], status);
493 if(U_FAILURE(status)){
494 errln("FAIL: " + t->getID()+ ".transliterate(Replaceable, int32_t[], UnicodeString, UErrorCode)-->" + (UnicodeString)u_errorName(status));
495 continue;
496 }
497 }else {
498 log = s + " => ";
499 t->finishTransliteration(s, index);
500 }
501 // Show the start index '{' and the cursor '|'
502 displayOutput(s, Data[i+1], log, index);
503
504 }
505
506 s="";
507 status=U_ZERO_ERROR;
508 index.contextStart = index.contextLimit = index.start = index.limit = 0;
509 logln("Testing transliterate(Replaceable, int32_t, UChar, UErrorCode)");
510 for(i=10; i<sizeof(Data)/sizeof(Data[0]); i=i+2){
511 UnicodeString log;
512 if (Data[i+0] != "") {
513 log = s + " + " + Data[i+0] + " -> ";
514 UChar c=Data[i+0].charAt(0);
515 t->transliterate(s, index, c, status);
516 if(U_FAILURE(status))
517 errln("FAIL: " + t->getID()+ ".transliterate(Replaceable, int32_t[], UChar, UErrorCode)-->" + (UnicodeString)u_errorName(status));
518 continue;
519 }else {
520 log = s + " => ";
521 t->finishTransliteration(s, index);
522 }
523 // Show the start index '{' and the cursor '|'
524 displayOutput(s, Data[i+1], log, index);
525 }
526
527 delete t;
528 }
529
TestKeyboardTransliterator2()530 void TransliteratorAPITest::TestKeyboardTransliterator2(){
531 UnicodeString Data[]={
532 //insertion, buffer, index[START], index[LIMIT], index[CURSOR]
533 //data for Any-Hex
534 "abc", UnicodeString("Initial String: add-\\u0061\\u0062\\u0063-", ""), "19", "20", "20",
535 "a", UnicodeString("In\\u0069\\u0061tial String: add-\\u0061\\u0062\\u0063-", ""), "2", "3", "2" ,
536 "b", UnicodeString("\\u0062In\\u0069\\u0061tial String: add-\\u0061\\u0062\\u0063-", ""), "0", "0", "0" ,
537 "", UnicodeString("\\u0062In\\u0069\\u0061tial String: add-\\u0061\\u0062\\u0063-", ""), "0", "0", "0" ,
538 //data for Latin-Devanagiri
539 CharsToUnicodeString("a\\u0304"), CharsToUnicodeString("Hindi -\\u0906-"), "6", "7", "6",
540 CharsToUnicodeString("ma\\u0304"), CharsToUnicodeString("Hindi -\\u0906\\u092E\\u093E-"), "7", "8", "7",
541 CharsToUnicodeString("ra\\u0304"), CharsToUnicodeString("Hi\\u0930\\u093Endi -\\u0906\\u092E\\u093E-"),"1", "2", "2",
542 CharsToUnicodeString(""), CharsToUnicodeString("Hi\\u0930\\u093Endi -\\u0906\\u092E\\u093E-"),"1", "2", "2"
543 //data for contracted-Expanded
544 // CharsToUnicodeString("\\u00C1"), CharsToUnicodeString("Ad\\u0041\\u0301d here:"), "1", "2", "1" ,
545 // CharsToUnicodeString("\\u00C0"), CharsToUnicodeString("Ad\\u0041\\u0301d here:\\u0041\\u0300"), "11", "11", "11",
546 // "", CharsToUnicodeString("Ad\\u0041\\u0301d here:\\u0041\\u0300"), "11", "11", "11",
547 };
548 Transliterator *t;
549 UnicodeString rs;
550 UnicodeString dataStr;
551 logln("Testing transliterate(Replaceable, int32_t, UnicodeString, UErrorCode)");
552 UErrorCode status = U_ZERO_ERROR;
553 UParseError parseError;
554 rs="Initial String: add--";
555 t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status);
556 if(t == 0)
557 dataerrln("FAIL : construction - %s", u_errorName(status));
558 else {
559 keyboardAux(t, Data, rs, 0, 20);
560 delete t;
561 }
562
563 rs="Hindi --";
564 t=Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseError, status);
565 if(t == 0)
566 dataerrln("FAIL : construction - %s", u_errorName(status));
567 else
568 keyboardAux(t, Data, rs, 20, 40);
569
570
571 // rs="Add here:";
572 // t=Transliterator::createInstance("Contracted-Expanded");
573 // keyboardAux(t, Data, rs, 35, 55);
574
575
576 delete t;
577 }
578
TestKeyboardTransliterator3()579 void TransliteratorAPITest::TestKeyboardTransliterator3(){
580 UnicodeString s="This is the main string";
581 UnicodeString Data[] = {
582 "0", "0", "0", "This is the main string",
583 "1", "3", "2", UnicodeString("Th\\u0069s is the main string", ""),
584 "20", "21", "20", UnicodeString("Th\\u0069s is the mai\\u006E string", "")
585 };
586
587 UErrorCode status=U_ZERO_ERROR;
588 UParseError parseError;
589 UTransPosition index={0, 0, 0, 0};
590 logln("Testing transliterate(Replaceable, int32_t, UErrorCode)");
591 Transliterator *t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status);
592 if(t == 0 || U_FAILURE(status)) {
593 errln("Error creating transliterator %s", u_errorName(status));
594 delete t;
595 return;
596 }
597 for(uint32_t i=0; i<sizeof(Data)/sizeof(Data[0]); i=i+4){
598 UnicodeString log;
599 index.contextStart=getInt(Data[i+0]);
600 index.contextLimit=index.limit=getInt(Data[i+1]);
601 index.start=getInt(Data[i+2]);
602 t->transliterate(s, index, status);
603 if(U_FAILURE(status)){
604 errln("FAIL: " + t->getID()+ ".transliterate(Replaceable, int32_t[], UErrorCode)-->" + (UnicodeString)u_errorName(status));
605 continue;
606 }
607 t->finishTransliteration(s, index);
608 log = s + " => ";
609 // Show the start index '{' and the cursor '|'
610 displayOutput(s, Data[i+3], log, index);
611 }
612
613 delete t;
614 }
TestNullTransliterator()615 void TransliteratorAPITest::TestNullTransliterator(){
616 UErrorCode status=U_ZERO_ERROR;
617 UnicodeString s("Transliterate using null transliterator");
618 Transliterator *nullTrans=Transliterator::createInstance("Any-Null", UTRANS_FORWARD, status);
619 int32_t transLimit;
620 int32_t start=0;
621 int32_t limit=s.length();
622 UnicodeString replaceable=s;
623 transLimit=nullTrans->transliterate(replaceable, start, limit);
624 if(transLimit != limit){
625 errln("ERROR: NullTransliterator->transliterate() failed");
626 }
627 doTest((UnicodeString)"nulTrans->transliterate", replaceable, s);
628 replaceable.remove();
629 replaceable.append(s);
630 UTransPosition index;
631 index.contextStart =start;
632 index.contextLimit = limit;
633 index.start = 0;
634 index.limit = limit;
635 nullTrans->finishTransliteration(replaceable, index);
636 if(index.start != limit){
637 errln("ERROR: NullTransliterator->handleTransliterate() failed");
638 }
639 doTest((UnicodeString)"NullTransliterator->handleTransliterate", replaceable, s);
640 callEverything(nullTrans, __LINE__);
641 delete nullTrans;
642
643
644 }
TestRegisterUnregister()645 void TransliteratorAPITest::TestRegisterUnregister(){
646
647 UErrorCode status=U_ZERO_ERROR;
648 /* Make sure it doesn't exist */
649 if (Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD, status) != NULL) {
650 errln("FAIL: TestA-TestB already registered\n");
651 return;
652 }
653 /* Check inverse too
654 if (Transliterator::createInstance("TestA-TestB",
655 (UTransDirection)UTRANS_REVERSE) != NULL) {
656 errln("FAIL: TestA-TestB inverse already registered\n");
657 return;
658 }
659 */
660 status =U_ZERO_ERROR;
661
662 /* Create it */
663 UParseError parseError;
664 Transliterator *t = Transliterator::createFromRules("TestA-TestB",
665 "a<>b",
666 UTRANS_FORWARD, parseError,
667 status);
668 /* Register it */
669 Transliterator::registerInstance(t);
670
671 /* Now check again -- should exist now*/
672 Transliterator *s = Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD, status);
673 if (s == NULL) {
674 errln("FAIL: TestA-TestB not registered\n");
675 return;
676 }
677 callEverything(s, __LINE__);
678 callEverything(t, __LINE__);
679 delete s;
680
681 /* Check inverse too
682 s = Transliterator::createInstance("TestA-TestB",
683 (UTransDirection)UTRANS_REVERSE);
684 if (s == NULL) {
685 errln("FAIL: TestA-TestB inverse not registered\n");
686 return;
687 }
688 delete s;
689 */
690
691 /*unregister the instance*/
692 Transliterator::unregister("TestA-TestB");
693 /* now Make sure it doesn't exist */
694 if (Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD, status) != NULL) {
695 errln("FAIL: TestA-TestB isn't unregistered\n");
696 return;
697 }
698
699 }
700
701
702 int gTestFilter1ClassID = 0;
703 int gTestFilter2ClassID = 0;
704 int gTestFilter3ClassID = 0;
705
706 /**
707 * Used by TestFiltering().
708 */
709 class TestFilter1 : public UnicodeFilter {
getDynamicClassID() const710 UClassID getDynamicClassID()const { return &gTestFilter1ClassID; }
clone() const711 virtual UnicodeFunctor* clone() const {
712 return new TestFilter1(*this);
713 }
contains(UChar32 c) const714 virtual UBool contains(UChar32 c) const {
715 if(c==0x63 || c==0x61 || c==0x43 || c==0x41)
716 return FALSE;
717 else
718 return TRUE;
719 }
720 // Stubs
toPattern(UnicodeString & result,UBool) const721 virtual UnicodeString& toPattern(UnicodeString& result,
722 UBool /*escapeUnprintable*/) const {
723 return result;
724 }
matchesIndexValue(uint8_t) const725 virtual UBool matchesIndexValue(uint8_t /*v*/) const {
726 return FALSE;
727 }
addMatchSetTo(UnicodeSet &) const728 virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {}
729 };
730 class TestFilter2 : public UnicodeFilter {
getDynamicClassID() const731 UClassID getDynamicClassID()const { return &gTestFilter2ClassID; }
clone() const732 virtual UnicodeFunctor* clone() const {
733 return new TestFilter2(*this);
734 }
contains(UChar32 c) const735 virtual UBool contains(UChar32 c) const {
736 if(c==0x65 || c==0x6c)
737 return FALSE;
738 else
739 return TRUE;
740 }
741 // Stubs
toPattern(UnicodeString & result,UBool) const742 virtual UnicodeString& toPattern(UnicodeString& result,
743 UBool /*escapeUnprintable*/) const {
744 return result;
745 }
matchesIndexValue(uint8_t) const746 virtual UBool matchesIndexValue(uint8_t /*v*/) const {
747 return FALSE;
748 }
addMatchSetTo(UnicodeSet &) const749 virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {}
750 };
751 class TestFilter3 : public UnicodeFilter {
getDynamicClassID() const752 UClassID getDynamicClassID()const { return &gTestFilter3ClassID; }
clone() const753 virtual UnicodeFunctor* clone() const {
754 return new TestFilter3(*this);
755 }
contains(UChar32 c) const756 virtual UBool contains(UChar32 c) const {
757 if(c==0x6f || c==0x77)
758 return FALSE;
759 else
760 return TRUE;
761 }
762 // Stubs
toPattern(UnicodeString & result,UBool) const763 virtual UnicodeString& toPattern(UnicodeString& result,
764 UBool /*escapeUnprintable*/) const {
765 return result;
766 }
matchesIndexValue(uint8_t) const767 virtual UBool matchesIndexValue(uint8_t /*v*/) const {
768 return FALSE;
769 }
addMatchSetTo(UnicodeSet &) const770 virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {}
771 };
772
773
TestGetAdoptFilter()774 void TransliteratorAPITest::TestGetAdoptFilter(){
775 UErrorCode status = U_ZERO_ERROR;
776 UParseError parseError;
777 Transliterator *t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status);
778 if(t == 0 || U_FAILURE(status)) {
779 errln("Error creating transliterator %s", u_errorName(status));
780 delete t;
781 return;
782 }
783 const UnicodeFilter *u=t->getFilter();
784 if(u != NULL){
785 errln("FAIL: getFilter failed. Didn't return null when the transliterator used no filtering");
786 delete t;
787 return;
788 }
789
790 UnicodeString got, temp, message;
791 UnicodeString data="ABCabcbbCBa";
792 temp = data;
793 t->transliterate(temp);
794 t->adoptFilter(new TestFilter1);
795
796 got = data;
797 t->transliterate(got);
798 UnicodeString exp=UnicodeString("A\\u0042Ca\\u0062c\\u0062\\u0062C\\u0042a", "");
799 message="transliteration after adoptFilter(a,A,c,C) ";
800 doTest(message, got, exp);
801
802 logln("Testing round trip");
803 t->adoptFilter((UnicodeFilter*)u);
804 if(t->getFilter() == NULL)
805 logln("OK: adoptFilter and getFilter round trip worked");
806 else
807 errln("FAIL: adoptFilter or getFilter round trip failed");
808
809 got = data;
810 t->transliterate(got);
811 exp=UnicodeString("\\u0041\\u0042\\u0043\\u0061\\u0062\\u0063\\u0062\\u0062\\u0043\\u0042\\u0061", "");
812 message="transliteration after adopting null filter";
813 doTest(message, got, exp);
814 message="adoptFilter round trip";
815 doTest("adoptFilter round trip", got, temp);
816
817 t->adoptFilter(new TestFilter2);
818 callEverything(t, __LINE__);
819 data="heelloe";
820 exp=UnicodeString("\\u0068eell\\u006Fe", "");
821 got = data;
822 t->transliterate(got);
823 message="transliteration using (e,l) filter";
824 doTest("transliteration using (e,l) filter", got, exp);
825
826 data="are well";
827 exp=UnicodeString("\\u0061\\u0072e\\u0020\\u0077ell", "");
828 got = data;
829 t->transliterate(got);
830 doTest(message, got, exp);
831
832 t->adoptFilter(new TestFilter3);
833 data="ho, wow!";
834 exp=UnicodeString("\\u0068o\\u002C\\u0020wow\\u0021", "");
835 got = data;
836 t->transliterate(got);
837 message="transliteration using (o,w) filter";
838 doTest("transliteration using (o,w) filter", got, exp);
839
840 data="owl";
841 exp=UnicodeString("ow\\u006C", "");
842 got = data;
843 t->transliterate(got);
844 doTest("transliteration using (o,w) filter", got, exp);
845
846 delete t;
847
848 }
849
850
851
keyboardAux(Transliterator * t,UnicodeString DATA[],UnicodeString & s,int32_t begin,int32_t end)852 void TransliteratorAPITest::keyboardAux(Transliterator *t, UnicodeString DATA[], UnicodeString& s, int32_t begin, int32_t end) {
853 UTransPosition index={0, 0, 0, 0};
854 UErrorCode status=U_ZERO_ERROR;
855 for (int32_t i=begin; i<end; i=i+5) {
856 UnicodeString log;
857 if (DATA[i+0] != "") {
858 log = s + " + " + DATA[i] + " -> ";
859 index.contextStart=getInt(DATA[i+2]);
860 index.contextLimit=index.limit=getInt(DATA[i+3]);
861 index.start=getInt(DATA[i+4]);
862 t->transliterate(s, index, DATA[i+0], status);
863 if(U_FAILURE(status)){
864 errln("FAIL: " + t->getID()+ ".transliterate(Replaceable, int32_t[], UnicodeString, UErrorCode)-->" + (UnicodeString)u_errorName(status));
865 continue;
866 }
867 log = s + " => ";
868 t->finishTransliteration(s, index);
869 }
870 // Show the start index '{' and the cursor '|'
871 displayOutput(s, DATA[i+1], log, index);
872
873 }
874 }
875
displayOutput(const UnicodeString & got,const UnicodeString & expected,UnicodeString & log,UTransPosition & index)876 void TransliteratorAPITest::displayOutput(const UnicodeString& got, const UnicodeString& expected, UnicodeString& log, UTransPosition& index){
877 // Show the start index '{' and the cursor '|'
878 UnicodeString a, b, c, d, e;
879 got.extractBetween(0, index.contextStart, a);
880 got.extractBetween(index.contextStart, index.start, b);
881 got.extractBetween(index.start, index.limit, c);
882 got.extractBetween(index.limit, index.contextLimit, d);
883 got.extractBetween(index.contextLimit, got.length(), e);
884 log.append(a).
885 append((UChar)0x7b/*{*/).
886 append(b).
887 append((UChar)0x7c/*|*/).
888 append(c).
889 append((UChar)0x7c).
890 append(d).
891 append((UChar)0x7d/*}*/).
892 append(e);
893 if (got == expected)
894 logln("OK:" + prettify(log));
895 else
896 errln("FAIL: " + prettify(log) + ", expected " + prettify(expected));
897 }
898
899
900 /*Internal Functions used*/
doTest(const UnicodeString & message,const UnicodeString & result,const UnicodeString & expected)901 void TransliteratorAPITest::doTest(const UnicodeString& message, const UnicodeString& result, const UnicodeString& expected){
902 if (prettify(result) == prettify(expected))
903 logln((UnicodeString)"Ok: " + prettify(message) + " passed \"" + prettify(expected) + "\"");
904 else
905 dataerrln((UnicodeString)"FAIL:" + message + " failed Got-->" + prettify(result)+ ", Expected--> " + prettify(expected) );
906 }
907
908
909 //
910 // callEverything call all of the const (non-destructive) methods on a
911 // transliterator, just to verify that they don't fail in some
912 // destructive way.
913 //
914 #define CEASSERT(a) {if (!(a)) { \
915 errln("FAIL at line %d from line %d: %s", __LINE__, line, #a); return; }}
916
callEverything(const Transliterator * tr,int line)917 void TransliteratorAPITest::callEverything(const Transliterator *tr, int line) {
918 Transliterator *clonedTR = tr->clone();
919 CEASSERT(clonedTR != NULL);
920
921 int32_t maxcl = tr->getMaximumContextLength();
922 CEASSERT(clonedTR->getMaximumContextLength() == maxcl);
923
924 UnicodeString id;
925 UnicodeString clonedId;
926 id = tr->getID();
927 clonedId = clonedTR->getID();
928 CEASSERT(id == clonedId);
929
930 const UnicodeFilter *filter = tr->getFilter();
931 const UnicodeFilter *clonedFilter = clonedTR->getFilter();
932 if (filter == NULL || clonedFilter == NULL) {
933 // If one filter is NULL they better both be NULL.
934 CEASSERT(filter == clonedFilter);
935 } else {
936 CEASSERT(filter != clonedFilter);
937 }
938
939 UnicodeString rules;
940 UnicodeString clonedRules;
941 rules = tr->toRules(rules, FALSE);
942 clonedRules = clonedTR->toRules(clonedRules, FALSE);
943 CEASSERT(rules == clonedRules);
944
945 UnicodeSet sourceSet;
946 UnicodeSet clonedSourceSet;
947 tr->getSourceSet(sourceSet);
948 clonedTR->getSourceSet(clonedSourceSet);
949 CEASSERT(clonedSourceSet == sourceSet);
950
951 UnicodeSet targetSet;
952 UnicodeSet clonedTargetSet;
953 tr->getTargetSet(targetSet);
954 clonedTR->getTargetSet(clonedTargetSet);
955 CEASSERT(targetSet == clonedTargetSet);
956
957 UClassID classID = tr->getDynamicClassID();
958 CEASSERT(classID == clonedTR->getDynamicClassID());
959 CEASSERT(classID != 0);
960
961 delete clonedTR;
962 }
963
964 static const int MyUnicodeFunctorTestClassID = 0;
965 class MyUnicodeFunctorTestClass : public UnicodeFunctor {
966 public:
clone() const967 virtual UnicodeFunctor* clone() const {return NULL;}
getStaticClassID(void)968 static UClassID getStaticClassID(void) {return (UClassID)&MyUnicodeFunctorTestClassID;}
getDynamicClassID(void) const969 virtual UClassID getDynamicClassID(void) const {return getStaticClassID();};
setData(const TransliterationRuleData *)970 virtual void setData(const TransliterationRuleData*) {}
971 };
972
TestUnicodeFunctor()973 void TransliteratorAPITest::TestUnicodeFunctor() {
974 MyUnicodeFunctorTestClass myClass;
975 if (myClass.toMatcher() != NULL) {
976 errln("FAIL: UnicodeFunctor::toMatcher did not return NULL");
977 }
978 if (myClass.toReplacer() != NULL) {
979 errln("FAIL: UnicodeFunctor::toReplacer did not return NULL");
980 }
981 }
982
983
984 #endif /* #if !UCONFIG_NO_TRANSLITERATION */
985