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
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)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
TestConstruction()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
TestCloneEqual()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
TestGetCount()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
TestGetSetAdoptTransliterator()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 */
split(const UnicodeString & str,UChar seperator,int32_t & count)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 }
TestTransliterate()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 //======================================================================
expect(const CompoundTransliterator & t,const UnicodeString & source,const UnicodeString & expectedResult)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
expectAux(const UnicodeString & tag,const UnicodeString & summary,UBool pass,const UnicodeString & expectedResult)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