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