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 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 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 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 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 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 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 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 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 } 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 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 } 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 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 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 } 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 } 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 { 710 UClassID getDynamicClassID()const { return &gTestFilter1ClassID; } 711 virtual UnicodeFunctor* clone() const { 712 return new TestFilter1(*this); 713 } 714 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 721 virtual UnicodeString& toPattern(UnicodeString& result, 722 UBool /*escapeUnprintable*/) const { 723 return result; 724 } 725 virtual UBool matchesIndexValue(uint8_t /*v*/) const { 726 return FALSE; 727 } 728 virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {} 729 }; 730 class TestFilter2 : public UnicodeFilter { 731 UClassID getDynamicClassID()const { return &gTestFilter2ClassID; } 732 virtual UnicodeFunctor* clone() const { 733 return new TestFilter2(*this); 734 } 735 virtual UBool contains(UChar32 c) const { 736 if(c==0x65 || c==0x6c) 737 return FALSE; 738 else 739 return TRUE; 740 } 741 // Stubs 742 virtual UnicodeString& toPattern(UnicodeString& result, 743 UBool /*escapeUnprintable*/) const { 744 return result; 745 } 746 virtual UBool matchesIndexValue(uint8_t /*v*/) const { 747 return FALSE; 748 } 749 virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {} 750 }; 751 class TestFilter3 : public UnicodeFilter { 752 UClassID getDynamicClassID()const { return &gTestFilter3ClassID; } 753 virtual UnicodeFunctor* clone() const { 754 return new TestFilter3(*this); 755 } 756 virtual UBool contains(UChar32 c) const { 757 if(c==0x6f || c==0x77) 758 return FALSE; 759 else 760 return TRUE; 761 } 762 // Stubs 763 virtual UnicodeString& toPattern(UnicodeString& result, 764 UBool /*escapeUnprintable*/) const { 765 return result; 766 } 767 virtual UBool matchesIndexValue(uint8_t /*v*/) const { 768 return FALSE; 769 } 770 virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {} 771 }; 772 773 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 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 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*/ 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 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: 967 virtual UnicodeFunctor* clone() const {return NULL;} 968 static UClassID getStaticClassID(void) {return (UClassID)&MyUnicodeFunctorTestClassID;} 969 virtual UClassID getDynamicClassID(void) const {return getStaticClassID();}; 970 virtual void setData(const TransliterationRuleData*) {} 971 }; 972 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