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