1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /************************************************************************
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 ************************************************************************/
13 #include "unicode/utypes.h"
15 #if !UCONFIG_NO_TRANSLITERATION
19 #include "unicode/utypes.h"
20 #include "unicode/translit.h"
21 #include "unicode/unifilt.h"
27 #include "unicode/rep.h"
28 #include "unicode/locid.h"
29 #include "unicode/uniset.h"
31 int32_t getInt(UnicodeString str
)
38 str
.extract(0, len
, buffer
, "");
43 //---------------------------------------------
45 //---------------------------------------------
48 TransliteratorAPITest::runIndexedTest(int32_t index
, UBool exec
,
49 const char* &name
, char* /*par*/) {
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;
71 void TransliteratorAPITest::TestgetID() {
72 UnicodeString trans
="Latin-Greek";
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
));
83 errln("FAIL: getID returned " + ID
+ " instead of Latin-Greek");
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){
93 t
= Transliterator::createInstance(ID
, UTRANS_FORWARD
, parseError
, status
);
99 errln("FAIL: getID() returned " + t
->getID() + " instead of " + ID
);
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");
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");
113 Transliterator
* t3
=t1
->clone();
114 Transliterator
* t4
=t2
->clone();
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");
122 Transliterator
* t5
=Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD
, parseError
, status
);
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");
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
));
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() ");
154 UnicodeString TransID
[]={
155 "Halfwidth-Fullwidth",
156 "Fullwidth-Halfwidth",
159 //"Arabic-Latin", // removed in 2.0
163 //"Hebrew-Latin", // removed in 2.0
172 for(uint32_t i
=0; i
<UPRV_LENGTHOF(TransID
); i
=i
+2){
173 Transliterator
*trans1
=Transliterator::createInstance(TransID
[i
], UTRANS_FORWARD
, parseError
, status
);
175 errln("FAIL: in instantiation for" + TransID
[i
]);
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]);
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
));
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");
218 void TransliteratorAPITest::TestGetDisplayName() {
219 UnicodeString dispNames
[]= {
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"
235 UnicodeString name
="";
237 UnicodeString message
;
238 UErrorCode status
= U_ZERO_ERROR
;
239 UParseError parseError
;
241 #if UCONFIG_NO_FORMATTING
242 logln("Skipping, UCONFIG_NO_FORMATTING is set\n");
246 for (uint32_t i
=0; i
<UPRV_LENGTHOF(dispNames
); i
=i
+2 ) {
247 t
= Transliterator::createInstance(dispNames
[i
+0], UTRANS_FORWARD
, parseError
, status
);
249 dataerrln("FAIL: construction: " + dispNames
[i
+0] + " - " + u_errorName(status
));
250 status
= U_ZERO_ERROR
;
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!!!
257 t
->getDisplayName(t
->getID(), Locale::getUS(), name
);
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]);
271 void TransliteratorAPITest::TestTransliterate1(){
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") ,
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"
287 UnicodeString gotResult
;
289 UnicodeString message
;
291 logln("Testing transliterate");
292 UErrorCode status
= U_ZERO_ERROR
;
293 UParseError parseError
;
295 for(uint32_t i
=0;i
<UPRV_LENGTHOF(Data
); i
=i
+3){
296 t
=Transliterator::createInstance(Data
[i
+0], UTRANS_FORWARD
, parseError
, status
);
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
;
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]);
310 t
->transliterate(temp
);
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]);
317 callEverything(t
, __LINE__
);
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")
334 logln("\n Testing transliterate(String, int, int, StringBuffer)");
336 UnicodeString gotResBuf
;
338 int32_t start
, limit
;
339 UErrorCode status
= U_ZERO_ERROR
;
340 UParseError parseError
;
342 for(uint32_t i
=0; i
<UPRV_LENGTHOF(Data2
); i
=i
+6){
343 t
=Transliterator::createInstance(Data2
[i
+0], UTRANS_FORWARD
, parseError
, status
);
345 dataerrln("FAIL: construction: " + prettify(Data2
[i
+0]) + " - " + u_errorName(status
));
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]);
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__
);
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
));
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");
377 errln("FAIL: start greater than limit value returned" + gotResBuf
);
380 callEverything(t
, __LINE__
);
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", ""),
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
));
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]);
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
);
421 UnicodeString context
;
423 if (parseError
.preContext
[0]) {
424 context
+= (UnicodeString
)" at " + parseError
.preContext
;
426 if (parseError
.postContext
[0]) {
427 context
+= (UnicodeString
)" | " + parseError
.postContext
;
429 errln((UnicodeString
)"FAIL: can't create Any-Hex, " +
430 (UnicodeString
)u_errorName(status
) + context
);
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
);
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()
452 for(uint32_t i
=0; i
<UPRV_LENGTHOF(index1
); i
++){
454 t
->transliterate(rs
, index1
[i
], insertion
, status
);
455 if(status
== U_ILLEGAL_ARGUMENT_ERROR
)
456 logln("OK: invalid index values handled correctly");
458 errln("FAIL: invalid index values didn't throw U_ILLEGAL_ARGUMENT_ERROR throw" + (UnicodeString
)u_errorName(status
));
463 void TransliteratorAPITest::TestKeyboardTransliterator1(){
464 UnicodeString Data
[]={
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", "") ,
472 "a", UnicodeString("\\u0061", "") ,
473 "b", UnicodeString("\\u0061\\u0062", "") ,
474 "z", UnicodeString("\\u0061\\u0062\\u007A", "") ,
475 "", UnicodeString("\\u0061\\u0062\\u007A", "")
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
));
486 //keyboardAux(t, Data);
487 UTransPosition index
={0, 0, 0, 0};
490 logln("Testing transliterate(Replaceable, int32_t, UnicodeString, UErrorCode)");
491 for (i
=0; i
<10; i
=i
+2) {
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
));
502 t
->finishTransliteration(s
, index
);
504 // Show the start index '{' and the cursor '|'
505 displayOutput(s
, Data
[i
+1], log
, index
);
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){
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
));
524 t
->finishTransliteration(s
, index
);
526 // Show the start index '{' and the cursor '|'
527 displayOutput(s
, Data
[i
+1], log
, index
);
533 void TransliteratorAPITest::TestKeyboardTransliterator2(){
534 UnicodeString Data
[]={
535 //insertion, buffer, index[START], index[LIMIT], index[CURSOR]
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",
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
);
560 dataerrln("FAIL : construction - %s", u_errorName(status
));
562 keyboardAux(t
, Data
, rs
, 0, 20);
567 t
=Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD
, parseError
, status
);
569 dataerrln("FAIL : construction - %s", u_errorName(status
));
571 keyboardAux(t
, Data
, rs
, 20, 40);
575 // t=Transliterator::createInstance("Contracted-Expanded");
576 // keyboardAux(t, Data, rs, 35, 55);
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", "")
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
));
600 for(uint32_t i
=0; i
<UPRV_LENGTHOF(Data
); i
=i
+4){
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
));
610 t
->finishTransliteration(s
, index
);
612 // Show the start index '{' and the cursor '|'
613 displayOutput(s
, Data
[i
+3], log
, index
);
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
);
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");
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
;
638 nullTrans
->finishTransliteration(replaceable
, index
);
639 if(index
.start
!= limit
){
640 errln("ERROR: NullTransliterator->handleTransliterate() failed");
642 doTest((UnicodeString
)"NullTransliterator->handleTransliterate", replaceable
, s
);
643 callEverything(nullTrans
, __LINE__
);
648 void TransliteratorAPITest::TestRegisterUnregister(){
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");
657 if (Transliterator::createInstance("TestA-TestB",
658 (UTransDirection)UTRANS_REVERSE) != NULL) {
659 errln("FAIL: TestA-TestB inverse already registered\n");
663 status
=U_ZERO_ERROR
;
666 UParseError parseError
;
667 Transliterator
*t
= Transliterator::createFromRules("TestA-TestB",
669 UTRANS_FORWARD
, parseError
,
672 Transliterator::registerInstance(t
);
674 /* Now check again -- should exist now*/
675 Transliterator
*s
= Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD
, status
);
677 errln("FAIL: TestA-TestB not registered\n");
680 callEverything(s
, __LINE__
);
681 callEverything(t
, __LINE__
);
685 s = Transliterator::createInstance("TestA-TestB",
686 (UTransDirection)UTRANS_REVERSE);
688 errln("FAIL: TestA-TestB inverse not registered\n");
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");
705 int gTestFilter1ClassID
= 0;
706 int gTestFilter2ClassID
= 0;
707 int gTestFilter3ClassID
= 0;
710 * Used by TestFiltering().
712 class TestFilter1
: public UnicodeFilter
{
713 UClassID
getDynamicClassID()const { return &gTestFilter1ClassID
; }
714 virtual UnicodeFunctor
* clone() const {
715 return new TestFilter1(*this);
717 virtual UBool
contains(UChar32 c
) const {
718 if(c
==0x63 || c
==0x61 || c
==0x43 || c
==0x41)
724 virtual UnicodeString
& toPattern(UnicodeString
& result
,
725 UBool
/*escapeUnprintable*/) const {
728 virtual UBool
matchesIndexValue(uint8_t /*v*/) const {
731 virtual void addMatchSetTo(UnicodeSet
& /*toUnionTo*/) const {}
733 class TestFilter2
: public UnicodeFilter
{
734 UClassID
getDynamicClassID()const { return &gTestFilter2ClassID
; }
735 virtual UnicodeFunctor
* clone() const {
736 return new TestFilter2(*this);
738 virtual UBool
contains(UChar32 c
) const {
739 if(c
==0x65 || c
==0x6c)
745 virtual UnicodeString
& toPattern(UnicodeString
& result
,
746 UBool
/*escapeUnprintable*/) const {
749 virtual UBool
matchesIndexValue(uint8_t /*v*/) const {
752 virtual void addMatchSetTo(UnicodeSet
& /*toUnionTo*/) const {}
754 class TestFilter3
: public UnicodeFilter
{
755 UClassID
getDynamicClassID()const { return &gTestFilter3ClassID
; }
756 virtual UnicodeFunctor
* clone() const {
757 return new TestFilter3(*this);
759 virtual UBool
contains(UChar32 c
) const {
760 if(c
==0x6f || c
==0x77)
766 virtual UnicodeString
& toPattern(UnicodeString
& result
,
767 UBool
/*escapeUnprintable*/) const {
770 virtual UBool
matchesIndexValue(uint8_t /*v*/) const {
773 virtual void addMatchSetTo(UnicodeSet
& /*toUnionTo*/) const {}
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
));
786 const UnicodeFilter
*u
=t
->getFilter();
788 errln("FAIL: getFilter failed. Didn't return null when the transliterator used no filtering");
793 UnicodeString got
, temp
, message
;
794 UnicodeString data
="ABCabcbbCBa";
796 t
->transliterate(temp
);
797 t
->adoptFilter(new TestFilter1
);
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
);
805 logln("Testing round trip");
806 t
->adoptFilter((UnicodeFilter
*)u
);
807 if(t
->getFilter() == NULL
)
808 logln("OK: adoptFilter and getFilter round trip worked");
810 errln("FAIL: adoptFilter or getFilter round trip failed");
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
);
820 t
->adoptFilter(new TestFilter2
);
821 callEverything(t
, __LINE__
);
823 exp
=UnicodeString("\\u0068eell\\u006Fe", "");
825 t
->transliterate(got
);
826 message
="transliteration using (e,l) filter";
827 doTest("transliteration using (e,l) filter", got
, exp
);
830 exp
=UnicodeString("\\u0061\\u0072e\\u0020\\u0077ell", "");
832 t
->transliterate(got
);
833 doTest(message
, got
, exp
);
835 t
->adoptFilter(new TestFilter3
);
837 exp
=UnicodeString("\\u0068o\\u002C\\u0020wow\\u0021", "");
839 t
->transliterate(got
);
840 message
="transliteration using (o,w) filter";
841 doTest("transliteration using (o,w) filter", got
, exp
);
844 exp
=UnicodeString("ow\\u006C", "");
846 t
->transliterate(got
);
847 doTest("transliteration using (o,w) filter", got
, exp
);
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) {
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
));
871 t
->finishTransliteration(s
, index
);
873 // Show the start index '{' and the cursor '|'
874 displayOutput(s
, DATA
[i
+1], log
, index
);
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
);
888 append((UChar
)0x7b/*{*/).
890 append((UChar
)0x7c/*|*/).
894 append((UChar
)0x7d/*}*/).
897 logln("OK:" + prettify(log
));
899 errln("FAIL: " + prettify(log
) + ", expected " + prettify(expected
));
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
) + "\"");
908 dataerrln((UnicodeString
)"FAIL:" + message
+ " failed Got-->" + prettify(result
)+ ", Expected--> " + prettify(expected
) );
913 // callEverything call all of the const (non-destructive) methods on a
914 // transliterator, just to verify that they don't fail in some
917 #define CEASSERT(a) {if (!(a)) { \
918 errln("FAIL at line %d from line %d: %s", __LINE__, line, #a); return; }}
920 void TransliteratorAPITest::callEverything(const Transliterator
*tr
, int line
) {
921 Transliterator
*clonedTR
= tr
->clone();
922 CEASSERT(clonedTR
!= NULL
);
924 int32_t maxcl
= tr
->getMaximumContextLength();
925 CEASSERT(clonedTR
->getMaximumContextLength() == maxcl
);
928 UnicodeString clonedId
;
930 clonedId
= clonedTR
->getID();
931 CEASSERT(id
== clonedId
);
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
);
939 CEASSERT(filter
!= clonedFilter
);
943 UnicodeString clonedRules
;
944 rules
= tr
->toRules(rules
, FALSE
);
945 clonedRules
= clonedTR
->toRules(clonedRules
, FALSE
);
946 CEASSERT(rules
== clonedRules
);
948 UnicodeSet sourceSet
;
949 UnicodeSet clonedSourceSet
;
950 tr
->getSourceSet(sourceSet
);
951 clonedTR
->getSourceSet(clonedSourceSet
);
952 CEASSERT(clonedSourceSet
== sourceSet
);
954 UnicodeSet targetSet
;
955 UnicodeSet clonedTargetSet
;
956 tr
->getTargetSet(targetSet
);
957 clonedTR
->getTargetSet(clonedTargetSet
);
958 CEASSERT(targetSet
== clonedTargetSet
);
960 UClassID classID
= tr
->getDynamicClassID();
961 CEASSERT(classID
== clonedTR
->getDynamicClassID());
962 CEASSERT(classID
!= 0);
967 static const int MyUnicodeFunctorTestClassID
= 0;
968 class MyUnicodeFunctorTestClass
: public UnicodeFunctor
{
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
*) {}
976 void TransliteratorAPITest::TestUnicodeFunctor() {
977 MyUnicodeFunctorTestClass myClass
;
978 if (myClass
.toMatcher() != NULL
) {
979 errln("FAIL: UnicodeFunctor::toMatcher did not return NULL");
981 if (myClass
.toReplacer() != NULL
) {
982 errln("FAIL: UnicodeFunctor::toReplacer did not return NULL");
987 #endif /* #if !UCONFIG_NO_TRANSLITERATION */