1 /*************************************************************************** 2 * 3 * Copyright (C) 2000-2009, International Business Machines 4 * Corporation and others. All Rights Reserved. 5 * 6 ************************************************************************ 7 * Date Name Description 8 * 03/09/2000 Madhu Creation. 9 ************************************************************************/ 10 11 #include "unicode/utypes.h" 12 13 #if !UCONFIG_NO_TRANSLITERATION 14 15 #include "cpdtrtst.h" 16 #include "unicode/utypes.h" 17 #include "unicode/translit.h" 18 #include "unicode/uniset.h" 19 #include "cpdtrans.h" 20 #include "cmemory.h" 21 22 //--------------------------------------------- 23 // runIndexedTest 24 //--------------------------------------------- 25 26 void 27 CompoundTransliteratorTest::runIndexedTest(int32_t index, UBool exec, 28 const char* &name, char* /*par*/) { 29 switch (index) { 30 TESTCASE(0,TestConstruction); 31 TESTCASE(1,TestCloneEqual); 32 TESTCASE(2,TestGetCount); 33 TESTCASE(3,TestGetSetAdoptTransliterator); 34 TESTCASE(4,TestTransliterate); 35 default: name = ""; break; 36 } 37 } 38 39 void CompoundTransliteratorTest::TestConstruction(){ 40 logln("Testing the construction of the compound Transliterator"); 41 UnicodeString names[]={"Greek-Latin", "Latin-Devanagari", "Devanagari-Latin", "Latin-Greek"}; 42 UParseError parseError; 43 UErrorCode status=U_ZERO_ERROR; 44 Transliterator* t1=Transliterator::createInstance(names[0], UTRANS_FORWARD, parseError, status); 45 Transliterator* t2=Transliterator::createInstance(names[1], UTRANS_FORWARD, parseError, status); 46 Transliterator* t3=Transliterator::createInstance(names[2], UTRANS_FORWARD, parseError, status); 47 Transliterator* t4=Transliterator::createInstance(names[3], UTRANS_FORWARD, parseError, status); 48 if(U_FAILURE(status)){ 49 dataerrln("Transliterator construction failed - %s", u_errorName(status)); 50 return; 51 } 52 53 54 Transliterator* transarray1[]={t1}; 55 Transliterator* transarray2[]={t1, t4}; 56 Transliterator* transarray3[]={t4, t1, t2}; 57 Transliterator* transarray4[]={t1, t2, t3, t4}; 58 59 Transliterator** transarray[4]; 60 transarray[0] = transarray1; 61 transarray[1] = transarray2; 62 transarray[2] = transarray3; 63 transarray[3] = transarray4; 64 65 const UnicodeString IDs[]={ 66 names[0], 67 names[0]+";"+names[3], 68 names[3]+";"+names[1]+";"+names[2], 69 names[0]+";"+names[1]+";"+names[2]+";"+names[3] 70 }; 71 72 uint16_t i=0; 73 for(i=0; i<4; i++){ 74 status = U_ZERO_ERROR; 75 CompoundTransliterator *cpdtrans=new CompoundTransliterator(IDs[i],parseError, status); 76 if (U_FAILURE(status)) { 77 errln("Construction using CompoundTransliterator(UnicodeString&, Direction, UnicodeFilter*) failed"); 78 } 79 delete cpdtrans; 80 81 CompoundTransliterator *cpdtrans2=new CompoundTransliterator(transarray[i], i+1); 82 if(cpdtrans2 == 0){ 83 errln("Construction using CompoundTransliterator(Transliterator* const transliterators[], " 84 "int32_t count, UnicodeFilter* adoptedFilter = 0) failed"); 85 continue; 86 } 87 CompoundTransliterator *copycpd=new CompoundTransliterator(*cpdtrans2); 88 if(copycpd->getCount() != cpdtrans2->getCount() || copycpd->getID() != cpdtrans2->getID()) { 89 errln("Copy construction failed"); 90 continue; 91 } 92 93 94 delete copycpd; 95 delete cpdtrans2; 96 97 } 98 { 99 /*Test Jitterbug 914 */ 100 UErrorCode err = U_ZERO_ERROR; 101 CompoundTransliterator cpdTrans(UnicodeString("Latin-Hangul"),UTRANS_REVERSE,NULL,parseError,err); 102 UnicodeString newID =cpdTrans.getID(); 103 if(newID!=UnicodeString("Hangul-Latin")){ 104 errln(UnicodeString("Test for Jitterbug 914 for cpdTrans(UnicodeString(\"Latin-Hangul\"),UTRANS_REVERSE,NULL,err) failed")); 105 } 106 } 107 delete t1; 108 delete t2; 109 delete t3; 110 delete t4; 111 112 } 113 114 void CompoundTransliteratorTest::TestCloneEqual(){ 115 logln("Testing the clone() and equality operator functions of Compound Transliterator"); 116 UErrorCode status = U_ZERO_ERROR; 117 UParseError parseError; 118 CompoundTransliterator *ct1=new CompoundTransliterator("Greek-Latin;Latin-Devanagari",parseError,status); 119 if(U_FAILURE(status)){ 120 dataerrln("construction failed - %s", u_errorName(status)); 121 delete ct1; 122 return; 123 } 124 CompoundTransliterator *ct2=new CompoundTransliterator("Greek-Latin", parseError, status); 125 if(U_FAILURE(status)){ 126 errln("construction failed"); 127 delete ct1; 128 delete ct2; 129 return; 130 } 131 CompoundTransliterator *copyct1=new CompoundTransliterator(*ct1); 132 if(copyct1 == 0){ 133 errln("copy construction failed"); 134 return; 135 } 136 CompoundTransliterator *copyct2=new CompoundTransliterator(*ct2); 137 if(copyct2 == 0){ 138 errln("copy construction failed"); 139 return; 140 } 141 CompoundTransliterator equalct1=*copyct1; 142 CompoundTransliterator equalct2=*copyct2; 143 144 if(copyct1->getID() != ct1->getID() || copyct2->getID() != ct2->getID() || 145 copyct1->getCount() != ct1->getCount() || copyct2->getCount() != ct2->getCount() || 146 copyct2->getID() == ct1->getID() || copyct1->getID() == ct2->getID() || 147 copyct2->getCount() == ct1->getCount() || copyct1->getCount() == ct2->getCount() ){ 148 errln("Error: copy constructors failed"); 149 } 150 151 if(equalct1.getID() != ct1->getID() || equalct2.getID() != ct2->getID() || 152 equalct1.getID() != copyct1->getID() || equalct2.getID() != copyct2->getID() || 153 equalct1.getCount() != ct1->getCount() || equalct2.getCount() != ct2->getCount() || 154 copyct2->getID() == ct1->getID() || copyct1->getID() == ct2->getID() || 155 equalct1.getCount() != copyct1->getCount() || equalct2.getCount() != copyct2->getCount() || 156 equalct2.getCount() == ct1->getCount() || equalct1.getCount() == ct2->getCount() ) { 157 errln("Error: =operator or copy constructor failed"); 158 } 159 160 CompoundTransliterator *clonect1a=(CompoundTransliterator*)ct1->clone(); 161 CompoundTransliterator *clonect1b=(CompoundTransliterator*)equalct1.clone(); 162 CompoundTransliterator *clonect2a=(CompoundTransliterator*)ct2->clone(); 163 CompoundTransliterator *clonect2b=(CompoundTransliterator*)copyct2->clone(); 164 165 166 if(clonect1a->getID() != ct1->getID() || clonect1a->getCount() != ct1->getCount() || 167 clonect1a->getID() != clonect1b->getID() || clonect1a->getCount() != clonect1b->getCount() || 168 clonect1a->getID() != equalct1.getID() || clonect1a->getCount() != equalct1.getCount() || 169 clonect1a->getID() != copyct1->getID() || clonect1a->getCount() != copyct1->getCount() || 170 171 clonect2b->getID() != ct2->getID() || clonect2a->getCount() != ct2->getCount() || 172 clonect2a->getID() != clonect2b->getID() || clonect2a->getCount() != clonect2b->getCount() || 173 clonect2a->getID() != equalct2.getID() || clonect2a->getCount() != equalct2.getCount() || 174 clonect2b->getID() != copyct2->getID() || clonect2b->getCount() != copyct2->getCount() ) { 175 errln("Error: clone() failed"); 176 } 177 178 delete ct1; 179 delete ct2; 180 delete copyct1; 181 delete copyct2; 182 delete clonect1a; 183 delete clonect1b; 184 delete clonect2a; 185 delete clonect2b; 186 187 } 188 189 void CompoundTransliteratorTest::TestGetCount(){ 190 logln("Testing the getCount() API of CompoundTransliterator"); 191 UErrorCode status = U_ZERO_ERROR; 192 UParseError parseError; 193 CompoundTransliterator *ct1=new CompoundTransliterator("Halfwidth-Fullwidth;Fullwidth-Halfwidth", parseError, status); 194 CompoundTransliterator *ct2=new CompoundTransliterator("Any-Hex;Hex-Any;Cyrillic-Latin;Latin-Cyrillic", parseError, status); 195 CompoundTransliterator *ct3=(CompoundTransliterator*)ct1; 196 if (U_FAILURE(status)) { 197 dataerrln("FAILED: CompoundTransliterator constructor failed - %s", u_errorName(status)); 198 return; 199 } 200 CompoundTransliterator *ct4=new CompoundTransliterator("Latin-Devanagari", parseError, status); 201 CompoundTransliterator *ct5=new CompoundTransliterator(*ct4); 202 203 if (U_FAILURE(status)) { 204 errln("FAILED: CompoundTransliterator constructor failed"); 205 return; 206 } 207 if(ct1->getCount() == ct2->getCount() || ct1->getCount() != ct3->getCount() || 208 ct2->getCount() == ct3->getCount() || 209 ct4->getCount() != ct5->getCount() || ct4->getCount() == ct1->getCount() || 210 ct4->getCount() == ct2->getCount() || ct4->getCount() == ct3->getCount() || 211 ct5->getCount() == ct2->getCount() || ct5->getCount() == ct3->getCount() ) { 212 errln("Error: getCount() failed"); 213 } 214 215 /* Quick test getTargetSet(), only test that it doesn't die. TODO: a better test. */ 216 UnicodeSet ts; 217 UnicodeSet *retUS = NULL; 218 retUS = &ct1->getTargetSet(ts); 219 if (retUS != &ts || ts.size() == 0) { 220 errln("CompoundTransliterator::getTargetSet() failed.\n"); 221 } 222 223 /* Quick test getSourceSet(), only test that it doesn't die. TODO: a better test. */ 224 UnicodeSet ss; 225 retUS = NULL; 226 retUS = &ct1->getSourceSet(ss); 227 if (retUS != &ss || ss.size() == 0) { 228 errln("CompoundTransliterator::getSourceSet() failed.\n"); 229 } 230 231 delete ct1; 232 delete ct2; 233 delete ct4; 234 delete ct5; 235 } 236 237 void CompoundTransliteratorTest::TestGetSetAdoptTransliterator(){ 238 logln("Testing the getTransliterator() API of CompoundTransliterator"); 239 UnicodeString ID("Latin-Greek;Greek-Latin;Latin-Devanagari;Devanagari-Latin;Latin-Cyrillic;Cyrillic-Latin;Any-Hex;Hex-Any"); 240 UErrorCode status = U_ZERO_ERROR; 241 UParseError parseError; 242 CompoundTransliterator *ct1=new CompoundTransliterator(ID, parseError, status); 243 if(U_FAILURE(status)){ 244 dataerrln("CompoundTransliterator construction failed - %s", u_errorName(status)); 245 return; 246 } 247 int32_t count=ct1->getCount(); 248 UnicodeString *array=split(ID, 0x003b, count); 249 int i; 250 for(i=0; i < count; i++){ 251 UnicodeString child= ct1->getTransliterator(i).getID(); 252 if(child != *(array+i)){ 253 errln("Error getTransliterator() failed: Expected->" + *(array+i) + " Got->" + child); 254 }else { 255 logln("OK: getTransliterator() passed: Expected->" + *(array+i) + " Got->" + child); 256 } 257 } 258 delete []array; 259 260 logln("Testing setTransliterator() API of CompoundTransliterator"); 261 UnicodeString ID2("Hex-Any;Any-Hex;Latin-Cyrillic;Cyrillic-Latin;Halfwidth-Fullwidth;Fullwidth-Halfwidth"); 262 array=split(ID2, 0x003b, count); 263 Transliterator** transarray=new Transliterator*[count]; 264 for(i=0;i<count;i++){ 265 transarray[i]=Transliterator::createInstance(*(array+i), UTRANS_FORWARD, parseError, status); 266 if(U_FAILURE(status)){ 267 errln("Error could not create Transliterator with ID :"+*(array+i)); 268 }else{ 269 logln("The ID for the transltierator created is " + transarray[i]->getID()); 270 } 271 status = U_ZERO_ERROR; 272 } 273 274 /*setTransliterator and adoptTransliterator */ 275 276 ct1->setTransliterators(transarray, count); 277 if(ct1->getCount() != count || ct1->getID() != ID2){ 278 errln((UnicodeString)"Error: setTransliterators() failed.\n\t Count:- expected->" + count + (UnicodeString)". got->" + ct1->getCount() + 279 (UnicodeString)"\n\tID :- expected->" + ID2 + (UnicodeString)". got->" + ct1->getID()); 280 } 281 else{ 282 logln("OK: setTransliterators() passed"); 283 } 284 /*UnicodeString temp; 285 for(i=0;i<count-1;i++){ 286 temp.append(ct1->getTransliterator(i).getID()); 287 temp.append(";"); 288 } 289 temp.append(ct1->getTransliterator(i).getID()); 290 if(temp != ID2){ 291 errln("Error: setTransliterator() failed. Expected->" + ID2 + "\nGot->" + temp); 292 } 293 else{ 294 logln("OK: setTransliterator() passed"); 295 }*/ 296 logln("Testing adoptTransliterator() API of CompoundTransliterator"); 297 UnicodeString ID3("Latin-Katakana"); 298 Transliterator **transarray2=(Transliterator **)uprv_malloc(sizeof(Transliterator*)*1); 299 transarray2[0] = Transliterator::createInstance(ID3,UTRANS_FORWARD,parseError,status); 300 if (transarray2[0] != 0) { 301 ct1->adoptTransliterators(transarray2, 1); 302 } 303 if(ct1->getCount() != 1 || ct1->getID() != ID3){ 304 errln((UnicodeString)"Error: adoptTransliterators() failed.\n\t Count:- expected->1" + (UnicodeString)". got->" + ct1->getCount() + 305 (UnicodeString)"\n\tID :- expected->" + ID3 + (UnicodeString)". got->" + ct1->getID()); 306 } 307 else{ 308 logln("OK: adoptTranslterator() passed"); 309 } 310 delete ct1; 311 for(i=0;i<count;i++){ 312 delete transarray[i]; 313 } 314 delete []transarray; 315 delete []array; 316 } 317 318 /** 319 * Splits a UnicodeString 320 */ 321 UnicodeString* CompoundTransliteratorTest::split(const UnicodeString& str, UChar seperator, int32_t& count) { 322 323 //get the count 324 int32_t i; 325 count =1; 326 for(i=0; i<str.length(); i++){ 327 if(str.charAt(i) == seperator) 328 count++; 329 } 330 // make an array 331 UnicodeString* result = new UnicodeString[count]; 332 int32_t last = 0; 333 int32_t current = 0; 334 for (i = 0; i < str.length(); ++i) { 335 if (str.charAt(i) == seperator) { 336 str.extractBetween(last, i, result[current]); 337 last = i+1; 338 current++; 339 } 340 } 341 str.extractBetween(last, i, result[current]); 342 return result; 343 } 344 void CompoundTransliteratorTest::TestTransliterate(){ 345 logln("Testing the handleTransliterate() API of CompoundTransliterator"); 346 UErrorCode status = U_ZERO_ERROR; 347 UParseError parseError; 348 CompoundTransliterator *ct1=new CompoundTransliterator("Any-Hex;Hex-Any",parseError, status); 349 if(U_FAILURE(status)){ 350 errln("CompoundTransliterator construction failed"); 351 }else { 352 #if 0 353 // handleTransliterate is a protected method that was erroneously made 354 // public. It is not public API that needs to be tested. 355 UnicodeString s("abcabc"); 356 expect(*ct1, s, s); 357 UTransPosition index = { 0, 0, 0, 0 }; 358 UnicodeString rsource2(s); 359 UnicodeString expectedResult=s; 360 ct1->handleTransliterate(rsource2, index, FALSE); 361 expectAux(ct1->getID() + ":String, index(0,0,0), incremental=FALSE", rsource2 + "->" + rsource2, rsource2==expectedResult, expectedResult); 362 UTransPosition _index = {1,3,2,3}; 363 uprv_memcpy(&index, &_index, sizeof(index)); 364 UnicodeString rsource3(s); 365 ct1->handleTransliterate(rsource3, index, TRUE); 366 expectAux(ct1->getID() + ":String, index(1,2,3), incremental=TRUE", rsource3 + "->" + rsource3, rsource3==expectedResult, expectedResult); 367 #endif 368 } 369 delete ct1; 370 UnicodeString Data[]={ 371 //ID, input string, transliterated string 372 "Any-Hex;Hex-Any;Any-Hex", "hello", UnicodeString("\\u0068\\u0065\\u006C\\u006C\\u006F", ""), 373 "Any-Hex;Hex-Any", "hello! How are you?", "hello! How are you?", 374 //"Devanagari-Latin;Latin-Devanagari", CharsToUnicodeString("\\u092D\\u0948'\\u0930'\\u0935"), CharsToUnicodeString("\\u092D\\u0948\\u0930\\u0935"), // quotes lost 375 "Latin-Cyrillic;Cyrillic-Latin", "a'b'k'd'e'f'g'h'i'j'Shch'shch'zh'h", "a'b'k'd'e'f'g'h'i'j'Shch'shch'zh'h", //"abkdefghijShchshchzhh", 376 "Latin-Greek;Greek-Latin", "ABGabgAKLMN", "ABGabgAKLMN", 377 //"Latin-Arabic;Arabic-Latin", "Ad'r'a'b'i'k'dh'dd'gh", "Adrabikdhddgh", 378 "Hiragana-Katakana", CharsToUnicodeString("\\u3041\\u308f\\u3099\\u306e\\u304b\\u3092\\u3099"), 379 CharsToUnicodeString("\\u30A1\\u30f7\\u30ce\\u30ab\\u30fa"), 380 "Hiragana-Katakana;Katakana-Hiragana", CharsToUnicodeString("\\u3041\\u308f\\u3099\\u306e\\u304b\\u3051"), 381 CharsToUnicodeString("\\u3041\\u308f\\u3099\\u306e\\u304b\\u3051"), 382 "Katakana-Hiragana;Hiragana-Katakana", CharsToUnicodeString("\\u30A1\\u30f7\\u30ce\\u30f5\\u30f6"), 383 CharsToUnicodeString("\\u30A1\\u30f7\\u30ce\\u30ab\\u30b1"), 384 "Latin-Katakana;Katakana-Latin", CharsToUnicodeString("vavivuvevohuzizuzonyinyunyasesuzezu"), 385 CharsToUnicodeString("vavivuvevohuzizuzonyinyunyasesuzezu"), 386 }; 387 uint32_t i; 388 for(i=0; i<sizeof(Data)/sizeof(Data[0]); i=i+3){ 389 UErrorCode status = U_ZERO_ERROR; 390 391 CompoundTransliterator *ct2=new CompoundTransliterator(Data[i+0], parseError, status); 392 if(U_FAILURE(status)){ 393 dataerrln("CompoundTransliterator construction failed for " + Data[i+0] + " - " + u_errorName(status)); 394 } else { 395 expect(*ct2, Data[i+1], Data[i+2]); 396 } 397 delete ct2; 398 } 399 400 } 401 402 403 404 //====================================================================== 405 // Support methods 406 //====================================================================== 407 void CompoundTransliteratorTest::expect(const CompoundTransliterator& t, 408 const UnicodeString& source, 409 const UnicodeString& expectedResult) { 410 411 UnicodeString rsource(source); 412 t.transliterate(rsource); 413 expectAux(t.getID() + ":Replaceable", source + "->" + rsource, rsource==expectedResult, expectedResult); 414 415 // Test transliterate (incremental) transliteration -- 416 rsource.remove(); 417 rsource.append(source); 418 UTransPosition index; 419 index.contextStart =0; 420 index.contextLimit = source.length(); 421 index.start = 0; 422 index.limit = source.length(); 423 UErrorCode ec = U_ZERO_ERROR; 424 t.transliterate(rsource, index, ec); 425 t.finishTransliteration(rsource,index); 426 expectAux(t.getID() + ":handleTransliterate ", source + "->" + rsource, rsource==expectedResult, expectedResult); 427 428 } 429 430 void CompoundTransliteratorTest::expectAux(const UnicodeString& tag, 431 const UnicodeString& summary, UBool pass, 432 const UnicodeString& expectedResult) { 433 if (pass) { 434 logln(UnicodeString("(")+tag+") " + prettify(summary)); 435 } else { 436 errln(UnicodeString("FAIL: (")+tag+") " 437 + prettify(summary) 438 + ", expected " + prettify(expectedResult)); 439 } 440 } 441 442 #endif /* #if !UCONFIG_NO_TRANSLITERATION */ 443