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