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
));
525 t
->finishTransliteration(s
, index
);
527 // Show the start index '{' and the cursor '|'
528 displayOutput(s
, Data
[i
+1], log
, index
);
534 void TransliteratorAPITest::TestKeyboardTransliterator2(){
535 UnicodeString Data
[]={
536 //insertion, buffer, index[START], index[LIMIT], index[CURSOR]
538 "abc", UnicodeString("Initial String: add-\\u0061\\u0062\\u0063-", ""), "19", "20", "20",
539 "a", UnicodeString("In\\u0069\\u0061tial String: add-\\u0061\\u0062\\u0063-", ""), "2", "3", "2" ,
540 "b", UnicodeString("\\u0062In\\u0069\\u0061tial String: add-\\u0061\\u0062\\u0063-", ""), "0", "0", "0" ,
541 "", UnicodeString("\\u0062In\\u0069\\u0061tial String: add-\\u0061\\u0062\\u0063-", ""), "0", "0", "0" ,
542 //data for Latin-Devanagiri
543 CharsToUnicodeString("a\\u0304"), CharsToUnicodeString("Hindi -\\u0906-"), "6", "7", "6",
544 CharsToUnicodeString("ma\\u0304"), CharsToUnicodeString("Hindi -\\u0906\\u092E\\u093E-"), "7", "8", "7",
545 CharsToUnicodeString("ra\\u0304"), CharsToUnicodeString("Hi\\u0930\\u093Endi -\\u0906\\u092E\\u093E-"),"1", "2", "2",
546 CharsToUnicodeString(""), CharsToUnicodeString("Hi\\u0930\\u093Endi -\\u0906\\u092E\\u093E-"),"1", "2", "2"
547 //data for contracted-Expanded
548 // CharsToUnicodeString("\\u00C1"), CharsToUnicodeString("Ad\\u0041\\u0301d here:"), "1", "2", "1" ,
549 // CharsToUnicodeString("\\u00C0"), CharsToUnicodeString("Ad\\u0041\\u0301d here:\\u0041\\u0300"), "11", "11", "11",
550 // "", CharsToUnicodeString("Ad\\u0041\\u0301d here:\\u0041\\u0300"), "11", "11", "11",
554 UnicodeString dataStr
;
555 logln("Testing transliterate(Replaceable, int32_t, UnicodeString, UErrorCode)");
556 UErrorCode status
= U_ZERO_ERROR
;
557 UParseError parseError
;
558 rs
="Initial String: add--";
559 t
=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD
, parseError
, status
);
561 dataerrln("FAIL : construction - %s", u_errorName(status
));
563 keyboardAux(t
, Data
, rs
, 0, 20);
568 t
=Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD
, parseError
, status
);
570 dataerrln("FAIL : construction - %s", u_errorName(status
));
572 keyboardAux(t
, Data
, rs
, 20, 40);
576 // t=Transliterator::createInstance("Contracted-Expanded");
577 // keyboardAux(t, Data, rs, 35, 55);
583 void TransliteratorAPITest::TestKeyboardTransliterator3(){
584 UnicodeString s
="This is the main string";
585 UnicodeString Data
[] = {
586 "0", "0", "0", "This is the main string",
587 "1", "3", "2", UnicodeString("Th\\u0069s is the main string", ""),
588 "20", "21", "20", UnicodeString("Th\\u0069s is the mai\\u006E string", "")
591 UErrorCode status
=U_ZERO_ERROR
;
592 UParseError parseError
;
593 UTransPosition index
={0, 0, 0, 0};
594 logln("Testing transliterate(Replaceable, int32_t, UErrorCode)");
595 Transliterator
*t
=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD
, parseError
, status
);
596 if(t
== 0 || U_FAILURE(status
)) {
597 errln("Error creating transliterator %s", u_errorName(status
));
601 for(uint32_t i
=0; i
<UPRV_LENGTHOF(Data
); i
=i
+4){
603 index
.contextStart
=getInt(Data
[i
+0]);
604 index
.contextLimit
=index
.limit
=getInt(Data
[i
+1]);
605 index
.start
=getInt(Data
[i
+2]);
606 t
->transliterate(s
, index
, status
);
607 if(U_FAILURE(status
)){
608 errln("FAIL: " + t
->getID()+ ".transliterate(Replaceable, int32_t[], UErrorCode)-->" + (UnicodeString
)u_errorName(status
));
611 t
->finishTransliteration(s
, index
);
613 // Show the start index '{' and the cursor '|'
614 displayOutput(s
, Data
[i
+3], log
, index
);
619 void TransliteratorAPITest::TestNullTransliterator(){
620 UErrorCode status
=U_ZERO_ERROR
;
621 UnicodeString
s("Transliterate using null transliterator");
622 Transliterator
*nullTrans
=Transliterator::createInstance("Any-Null", UTRANS_FORWARD
, status
);
625 int32_t limit
=s
.length();
626 UnicodeString replaceable
=s
;
627 transLimit
=nullTrans
->transliterate(replaceable
, start
, limit
);
628 if(transLimit
!= limit
){
629 errln("ERROR: NullTransliterator->transliterate() failed");
631 doTest((UnicodeString
)"nulTrans->transliterate", replaceable
, s
);
632 replaceable
.remove();
633 replaceable
.append(s
);
634 UTransPosition index
;
635 index
.contextStart
=start
;
636 index
.contextLimit
= limit
;
639 nullTrans
->finishTransliteration(replaceable
, index
);
640 if(index
.start
!= limit
){
641 errln("ERROR: NullTransliterator->handleTransliterate() failed");
643 doTest((UnicodeString
)"NullTransliterator->handleTransliterate", replaceable
, s
);
644 callEverything(nullTrans
, __LINE__
);
649 void TransliteratorAPITest::TestRegisterUnregister(){
651 UErrorCode status
=U_ZERO_ERROR
;
652 /* Make sure it doesn't exist */
653 if (Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD
, status
) != NULL
) {
654 errln("FAIL: TestA-TestB already registered\n");
658 if (Transliterator::createInstance("TestA-TestB",
659 (UTransDirection)UTRANS_REVERSE) != NULL) {
660 errln("FAIL: TestA-TestB inverse already registered\n");
664 status
=U_ZERO_ERROR
;
667 UParseError parseError
;
668 Transliterator
*t
= Transliterator::createFromRules("TestA-TestB",
670 UTRANS_FORWARD
, parseError
,
673 Transliterator::registerInstance(t
);
675 /* Now check again -- should exist now*/
676 Transliterator
*s
= Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD
, status
);
678 errln("FAIL: TestA-TestB not registered\n");
681 callEverything(s
, __LINE__
);
682 callEverything(t
, __LINE__
);
686 s = Transliterator::createInstance("TestA-TestB",
687 (UTransDirection)UTRANS_REVERSE);
689 errln("FAIL: TestA-TestB inverse not registered\n");
695 /*unregister the instance*/
696 Transliterator::unregister("TestA-TestB");
697 /* now Make sure it doesn't exist */
698 if (Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD
, status
) != NULL
) {
699 errln("FAIL: TestA-TestB isn't unregistered\n");
706 int gTestFilter1ClassID
= 0;
707 int gTestFilter2ClassID
= 0;
708 int gTestFilter3ClassID
= 0;
711 * Used by TestFiltering().
713 class TestFilter1
: public UnicodeFilter
{
714 UClassID
getDynamicClassID()const { return &gTestFilter1ClassID
; }
715 virtual UnicodeFunctor
* clone() const {
716 return new TestFilter1(*this);
718 virtual UBool
contains(UChar32 c
) const {
719 if(c
==0x63 || c
==0x61 || c
==0x43 || c
==0x41)
725 virtual UnicodeString
& toPattern(UnicodeString
& result
,
726 UBool
/*escapeUnprintable*/) const {
729 virtual UBool
matchesIndexValue(uint8_t /*v*/) const {
732 virtual void addMatchSetTo(UnicodeSet
& /*toUnionTo*/) const {}
734 class TestFilter2
: public UnicodeFilter
{
735 UClassID
getDynamicClassID()const { return &gTestFilter2ClassID
; }
736 virtual UnicodeFunctor
* clone() const {
737 return new TestFilter2(*this);
739 virtual UBool
contains(UChar32 c
) const {
740 if(c
==0x65 || c
==0x6c)
746 virtual UnicodeString
& toPattern(UnicodeString
& result
,
747 UBool
/*escapeUnprintable*/) const {
750 virtual UBool
matchesIndexValue(uint8_t /*v*/) const {
753 virtual void addMatchSetTo(UnicodeSet
& /*toUnionTo*/) const {}
755 class TestFilter3
: public UnicodeFilter
{
756 UClassID
getDynamicClassID()const { return &gTestFilter3ClassID
; }
757 virtual UnicodeFunctor
* clone() const {
758 return new TestFilter3(*this);
760 virtual UBool
contains(UChar32 c
) const {
761 if(c
==0x6f || c
==0x77)
767 virtual UnicodeString
& toPattern(UnicodeString
& result
,
768 UBool
/*escapeUnprintable*/) const {
771 virtual UBool
matchesIndexValue(uint8_t /*v*/) const {
774 virtual void addMatchSetTo(UnicodeSet
& /*toUnionTo*/) const {}
778 void TransliteratorAPITest::TestGetAdoptFilter(){
779 UErrorCode status
= U_ZERO_ERROR
;
780 UParseError parseError
;
781 Transliterator
*t
=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD
, parseError
, status
);
782 if(t
== 0 || U_FAILURE(status
)) {
783 errln("Error creating transliterator %s", u_errorName(status
));
787 const UnicodeFilter
*u
=t
->getFilter();
789 errln("FAIL: getFilter failed. Didn't return null when the transliterator used no filtering");
794 UnicodeString got
, temp
, message
;
795 UnicodeString data
="ABCabcbbCBa";
797 t
->transliterate(temp
);
798 t
->adoptFilter(new TestFilter1
);
801 t
->transliterate(got
);
802 UnicodeString exp
=UnicodeString("A\\u0042Ca\\u0062c\\u0062\\u0062C\\u0042a", "");
803 message
="transliteration after adoptFilter(a,A,c,C) ";
804 doTest(message
, got
, exp
);
806 logln("Testing round trip");
807 t
->adoptFilter((UnicodeFilter
*)u
);
808 if(t
->getFilter() == NULL
)
809 logln("OK: adoptFilter and getFilter round trip worked");
811 errln("FAIL: adoptFilter or getFilter round trip failed");
814 t
->transliterate(got
);
815 exp
=UnicodeString("\\u0041\\u0042\\u0043\\u0061\\u0062\\u0063\\u0062\\u0062\\u0043\\u0042\\u0061", "");
816 message
="transliteration after adopting null filter";
817 doTest(message
, got
, exp
);
818 message
="adoptFilter round trip";
819 doTest("adoptFilter round trip", got
, temp
);
821 t
->adoptFilter(new TestFilter2
);
822 callEverything(t
, __LINE__
);
824 exp
=UnicodeString("\\u0068eell\\u006Fe", "");
826 t
->transliterate(got
);
827 message
="transliteration using (e,l) filter";
828 doTest("transliteration using (e,l) filter", got
, exp
);
831 exp
=UnicodeString("\\u0061\\u0072e\\u0020\\u0077ell", "");
833 t
->transliterate(got
);
834 doTest(message
, got
, exp
);
836 t
->adoptFilter(new TestFilter3
);
838 exp
=UnicodeString("\\u0068o\\u002C\\u0020wow\\u0021", "");
840 t
->transliterate(got
);
841 message
="transliteration using (o,w) filter";
842 doTest("transliteration using (o,w) filter", got
, exp
);
845 exp
=UnicodeString("ow\\u006C", "");
847 t
->transliterate(got
);
848 doTest("transliteration using (o,w) filter", got
, exp
);
856 void TransliteratorAPITest::keyboardAux(Transliterator
*t
, UnicodeString DATA
[], UnicodeString
& s
, int32_t begin
, int32_t end
) {
857 UTransPosition index
={0, 0, 0, 0};
858 UErrorCode status
=U_ZERO_ERROR
;
859 for (int32_t i
=begin
; i
<end
; i
=i
+5) {
861 if (DATA
[i
+0] != "") {
862 log
= s
+ " + " + DATA
[i
] + " -> ";
863 index
.contextStart
=getInt(DATA
[i
+2]);
864 index
.contextLimit
=index
.limit
=getInt(DATA
[i
+3]);
865 index
.start
=getInt(DATA
[i
+4]);
866 t
->transliterate(s
, index
, DATA
[i
+0], status
);
867 if(U_FAILURE(status
)){
868 errln("FAIL: " + t
->getID()+ ".transliterate(Replaceable, int32_t[], UnicodeString, UErrorCode)-->" + (UnicodeString
)u_errorName(status
));
872 t
->finishTransliteration(s
, index
);
874 // Show the start index '{' and the cursor '|'
875 displayOutput(s
, DATA
[i
+1], log
, index
);
880 void TransliteratorAPITest::displayOutput(const UnicodeString
& got
, const UnicodeString
& expected
, UnicodeString
& log
, UTransPosition
& index
){
881 // Show the start index '{' and the cursor '|'
882 UnicodeString a
, b
, c
, d
, e
;
883 got
.extractBetween(0, index
.contextStart
, a
);
884 got
.extractBetween(index
.contextStart
, index
.start
, b
);
885 got
.extractBetween(index
.start
, index
.limit
, c
);
886 got
.extractBetween(index
.limit
, index
.contextLimit
, d
);
887 got
.extractBetween(index
.contextLimit
, got
.length(), e
);
889 append((UChar
)0x7b/*{*/).
891 append((UChar
)0x7c/*|*/).
895 append((UChar
)0x7d/*}*/).
898 logln("OK:" + prettify(log
));
900 errln("FAIL: " + prettify(log
) + ", expected " + prettify(expected
));
904 /*Internal Functions used*/
905 void TransliteratorAPITest::doTest(const UnicodeString
& message
, const UnicodeString
& result
, const UnicodeString
& expected
){
906 if (prettify(result
) == prettify(expected
))
907 logln((UnicodeString
)"Ok: " + prettify(message
) + " passed \"" + prettify(expected
) + "\"");
909 dataerrln((UnicodeString
)"FAIL:" + message
+ " failed Got-->" + prettify(result
)+ ", Expected--> " + prettify(expected
) );
914 // callEverything call all of the const (non-destructive) methods on a
915 // transliterator, just to verify that they don't fail in some
918 #define CEASSERT(a) {if (!(a)) { \
919 errln("FAIL at line %d from line %d: %s", __LINE__, line, #a); return; }}
921 void TransliteratorAPITest::callEverything(const Transliterator
*tr
, int line
) {
922 Transliterator
*clonedTR
= tr
->clone();
923 CEASSERT(clonedTR
!= NULL
);
925 int32_t maxcl
= tr
->getMaximumContextLength();
926 CEASSERT(clonedTR
->getMaximumContextLength() == maxcl
);
929 UnicodeString clonedId
;
931 clonedId
= clonedTR
->getID();
932 CEASSERT(id
== clonedId
);
934 const UnicodeFilter
*filter
= tr
->getFilter();
935 const UnicodeFilter
*clonedFilter
= clonedTR
->getFilter();
936 if (filter
== NULL
|| clonedFilter
== NULL
) {
937 // If one filter is NULL they better both be NULL.
938 CEASSERT(filter
== clonedFilter
);
940 CEASSERT(filter
!= clonedFilter
);
944 UnicodeString clonedRules
;
945 rules
= tr
->toRules(rules
, FALSE
);
946 clonedRules
= clonedTR
->toRules(clonedRules
, FALSE
);
947 CEASSERT(rules
== clonedRules
);
949 UnicodeSet sourceSet
;
950 UnicodeSet clonedSourceSet
;
951 tr
->getSourceSet(sourceSet
);
952 clonedTR
->getSourceSet(clonedSourceSet
);
953 CEASSERT(clonedSourceSet
== sourceSet
);
955 UnicodeSet targetSet
;
956 UnicodeSet clonedTargetSet
;
957 tr
->getTargetSet(targetSet
);
958 clonedTR
->getTargetSet(clonedTargetSet
);
959 CEASSERT(targetSet
== clonedTargetSet
);
961 UClassID classID
= tr
->getDynamicClassID();
962 CEASSERT(classID
== clonedTR
->getDynamicClassID());
963 CEASSERT(classID
!= 0);
968 static const int MyUnicodeFunctorTestClassID
= 0;
969 class MyUnicodeFunctorTestClass
: public UnicodeFunctor
{
971 virtual UnicodeFunctor
* clone() const {return NULL
;}
972 static UClassID
getStaticClassID(void) {return (UClassID
)&MyUnicodeFunctorTestClassID
;}
973 virtual UClassID
getDynamicClassID(void) const {return getStaticClassID();};
974 virtual void setData(const TransliterationRuleData
*) {}
977 void TransliteratorAPITest::TestUnicodeFunctor() {
978 MyUnicodeFunctorTestClass myClass
;
979 if (myClass
.toMatcher() != NULL
) {
980 errln("FAIL: UnicodeFunctor::toMatcher did not return NULL");
982 if (myClass
.toReplacer() != NULL
) {
983 errln("FAIL: UnicodeFunctor::toReplacer did not return NULL");
988 #endif /* #if !UCONFIG_NO_TRANSLITERATION */