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