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
getInt(UnicodeString str)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
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)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
TestgetID()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
TestgetInverse()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
TestClone()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
TestGetDisplayName()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
TestTransliterate1()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
TestTransliterate2()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 }
TestTransliterate3()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
TestSimpleKeyboardTransliterator()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 }
TestKeyboardTransliterator1()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 }
523 } else {
524 log = s + " => ";
525 t->finishTransliteration(s, index);
526 }
527 // Show the start index '{' and the cursor '|'
528 displayOutput(s, Data[i+1], log, index);
529 }
530
531 delete t;
532 }
533
TestKeyboardTransliterator2()534 void TransliteratorAPITest::TestKeyboardTransliterator2(){
535 UnicodeString Data[]={
536 //insertion, buffer, index[START], index[LIMIT], index[CURSOR]
537 //data for Any-Hex
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",
551 };
552 Transliterator *t;
553 UnicodeString rs;
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);
560 if(t == 0)
561 dataerrln("FAIL : construction - %s", u_errorName(status));
562 else {
563 keyboardAux(t, Data, rs, 0, 20);
564 delete t;
565 }
566
567 rs="Hindi --";
568 t=Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseError, status);
569 if(t == 0)
570 dataerrln("FAIL : construction - %s", u_errorName(status));
571 else
572 keyboardAux(t, Data, rs, 20, 40);
573
574
575 // rs="Add here:";
576 // t=Transliterator::createInstance("Contracted-Expanded");
577 // keyboardAux(t, Data, rs, 35, 55);
578
579
580 delete t;
581 }
582
TestKeyboardTransliterator3()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", "")
589 };
590
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));
598 delete t;
599 return;
600 }
601 for(uint32_t i=0; i<UPRV_LENGTHOF(Data); i=i+4){
602 UnicodeString log;
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));
609 continue;
610 }
611 t->finishTransliteration(s, index);
612 log = s + " => ";
613 // Show the start index '{' and the cursor '|'
614 displayOutput(s, Data[i+3], log, index);
615 }
616
617 delete t;
618 }
TestNullTransliterator()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);
623 int32_t transLimit;
624 int32_t start=0;
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");
630 }
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;
637 index.start = 0;
638 index.limit = limit;
639 nullTrans->finishTransliteration(replaceable, index);
640 if(index.start != limit){
641 errln("ERROR: NullTransliterator->handleTransliterate() failed");
642 }
643 doTest((UnicodeString)"NullTransliterator->handleTransliterate", replaceable, s);
644 callEverything(nullTrans, __LINE__);
645 delete nullTrans;
646
647
648 }
TestRegisterUnregister()649 void TransliteratorAPITest::TestRegisterUnregister(){
650
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");
655 return;
656 }
657 /* Check inverse too
658 if (Transliterator::createInstance("TestA-TestB",
659 (UTransDirection)UTRANS_REVERSE) != NULL) {
660 errln("FAIL: TestA-TestB inverse already registered\n");
661 return;
662 }
663 */
664 status =U_ZERO_ERROR;
665
666 /* Create it */
667 UParseError parseError;
668 Transliterator *t = Transliterator::createFromRules("TestA-TestB",
669 "a<>b",
670 UTRANS_FORWARD, parseError,
671 status);
672 /* Register it */
673 Transliterator::registerInstance(t);
674
675 /* Now check again -- should exist now*/
676 Transliterator *s = Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD, status);
677 if (s == NULL) {
678 errln("FAIL: TestA-TestB not registered\n");
679 return;
680 }
681 callEverything(s, __LINE__);
682 callEverything(t, __LINE__);
683 delete s;
684
685 /* Check inverse too
686 s = Transliterator::createInstance("TestA-TestB",
687 (UTransDirection)UTRANS_REVERSE);
688 if (s == NULL) {
689 errln("FAIL: TestA-TestB inverse not registered\n");
690 return;
691 }
692 delete s;
693 */
694
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");
700 return;
701 }
702
703 }
704
705
706 int gTestFilter1ClassID = 0;
707 int gTestFilter2ClassID = 0;
708 int gTestFilter3ClassID = 0;
709
710 /**
711 * Used by TestFiltering().
712 */
713 class TestFilter1 : public UnicodeFilter {
getDynamicClassID() const714 UClassID getDynamicClassID()const { return &gTestFilter1ClassID; }
clone() const715 virtual TestFilter1* clone() const {
716 return new TestFilter1(*this);
717 }
contains(UChar32 c) const718 virtual UBool contains(UChar32 c) const {
719 if(c==0x63 || c==0x61 || c==0x43 || c==0x41)
720 return FALSE;
721 else
722 return TRUE;
723 }
724 // Stubs
toPattern(UnicodeString & result,UBool) const725 virtual UnicodeString& toPattern(UnicodeString& result,
726 UBool /*escapeUnprintable*/) const {
727 return result;
728 }
matchesIndexValue(uint8_t) const729 virtual UBool matchesIndexValue(uint8_t /*v*/) const {
730 return FALSE;
731 }
addMatchSetTo(UnicodeSet &) const732 virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {}
733 };
734 class TestFilter2 : public UnicodeFilter {
getDynamicClassID() const735 UClassID getDynamicClassID()const { return &gTestFilter2ClassID; }
clone() const736 virtual TestFilter2* clone() const {
737 return new TestFilter2(*this);
738 }
contains(UChar32 c) const739 virtual UBool contains(UChar32 c) const {
740 if(c==0x65 || c==0x6c)
741 return FALSE;
742 else
743 return TRUE;
744 }
745 // Stubs
toPattern(UnicodeString & result,UBool) const746 virtual UnicodeString& toPattern(UnicodeString& result,
747 UBool /*escapeUnprintable*/) const {
748 return result;
749 }
matchesIndexValue(uint8_t) const750 virtual UBool matchesIndexValue(uint8_t /*v*/) const {
751 return FALSE;
752 }
addMatchSetTo(UnicodeSet &) const753 virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {}
754 };
755 class TestFilter3 : public UnicodeFilter {
getDynamicClassID() const756 UClassID getDynamicClassID()const { return &gTestFilter3ClassID; }
clone() const757 virtual TestFilter3* clone() const {
758 return new TestFilter3(*this);
759 }
contains(UChar32 c) const760 virtual UBool contains(UChar32 c) const {
761 if(c==0x6f || c==0x77)
762 return FALSE;
763 else
764 return TRUE;
765 }
766 // Stubs
toPattern(UnicodeString & result,UBool) const767 virtual UnicodeString& toPattern(UnicodeString& result,
768 UBool /*escapeUnprintable*/) const {
769 return result;
770 }
matchesIndexValue(uint8_t) const771 virtual UBool matchesIndexValue(uint8_t /*v*/) const {
772 return FALSE;
773 }
addMatchSetTo(UnicodeSet &) const774 virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {}
775 };
776
777
TestGetAdoptFilter()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));
784 delete t;
785 return;
786 }
787 const UnicodeFilter *u=t->getFilter();
788 if(u != NULL){
789 errln("FAIL: getFilter failed. Didn't return null when the transliterator used no filtering");
790 delete t;
791 return;
792 }
793
794 UnicodeString got, temp, message;
795 UnicodeString data="ABCabcbbCBa";
796 temp = data;
797 t->transliterate(temp);
798 t->adoptFilter(new TestFilter1);
799
800 got = data;
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);
805
806 logln("Testing round trip");
807 t->adoptFilter((UnicodeFilter*)u);
808 if(t->getFilter() == NULL)
809 logln("OK: adoptFilter and getFilter round trip worked");
810 else
811 errln("FAIL: adoptFilter or getFilter round trip failed");
812
813 got = data;
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);
820
821 t->adoptFilter(new TestFilter2);
822 callEverything(t, __LINE__);
823 data="heelloe";
824 exp=UnicodeString("\\u0068eell\\u006Fe", "");
825 got = data;
826 t->transliterate(got);
827 message="transliteration using (e,l) filter";
828 doTest("transliteration using (e,l) filter", got, exp);
829
830 data="are well";
831 exp=UnicodeString("\\u0061\\u0072e\\u0020\\u0077ell", "");
832 got = data;
833 t->transliterate(got);
834 doTest(message, got, exp);
835
836 t->adoptFilter(new TestFilter3);
837 data="ho, wow!";
838 exp=UnicodeString("\\u0068o\\u002C\\u0020wow\\u0021", "");
839 got = data;
840 t->transliterate(got);
841 message="transliteration using (o,w) filter";
842 doTest("transliteration using (o,w) filter", got, exp);
843
844 data="owl";
845 exp=UnicodeString("ow\\u006C", "");
846 got = data;
847 t->transliterate(got);
848 doTest("transliteration using (o,w) filter", got, exp);
849
850 delete t;
851
852 }
853
854
855
keyboardAux(Transliterator * t,UnicodeString DATA[],UnicodeString & s,int32_t begin,int32_t end)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) {
860 UnicodeString log;
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));
869 continue;
870 }
871 log = s + " => ";
872 t->finishTransliteration(s, index);
873 }
874 // Show the start index '{' and the cursor '|'
875 displayOutput(s, DATA[i+1], log, index);
876
877 }
878 }
879
displayOutput(const UnicodeString & got,const UnicodeString & expected,UnicodeString & log,UTransPosition & 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);
888 log.append(a).
889 append((UChar)0x7b/*{*/).
890 append(b).
891 append((UChar)0x7c/*|*/).
892 append(c).
893 append((UChar)0x7c).
894 append(d).
895 append((UChar)0x7d/*}*/).
896 append(e);
897 if (got == expected)
898 logln("OK:" + prettify(log));
899 else
900 errln("FAIL: " + prettify(log) + ", expected " + prettify(expected));
901 }
902
903
904 /*Internal Functions used*/
doTest(const UnicodeString & message,const UnicodeString & result,const UnicodeString & expected)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) + "\"");
908 else
909 dataerrln((UnicodeString)"FAIL:" + message + " failed Got-->" + prettify(result)+ ", Expected--> " + prettify(expected) );
910 }
911
912
913 //
914 // callEverything call all of the const (non-destructive) methods on a
915 // transliterator, just to verify that they don't fail in some
916 // destructive way.
917 //
918 #define CEASSERT(a) UPRV_BLOCK_MACRO_BEGIN { \
919 if (!(a)) { \
920 errln("FAIL at line %d from line %d: %s", __LINE__, line, #a); \
921 return; \
922 } \
923 } UPRV_BLOCK_MACRO_END
924
callEverything(const Transliterator * tr,int line)925 void TransliteratorAPITest::callEverything(const Transliterator *tr, int line) {
926 Transliterator *clonedTR = tr->clone();
927 CEASSERT(clonedTR != NULL);
928
929 int32_t maxcl = tr->getMaximumContextLength();
930 CEASSERT(clonedTR->getMaximumContextLength() == maxcl);
931
932 UnicodeString id;
933 UnicodeString clonedId;
934 id = tr->getID();
935 clonedId = clonedTR->getID();
936 CEASSERT(id == clonedId);
937
938 const UnicodeFilter *filter = tr->getFilter();
939 const UnicodeFilter *clonedFilter = clonedTR->getFilter();
940 if (filter == NULL || clonedFilter == NULL) {
941 // If one filter is NULL they better both be NULL.
942 CEASSERT(filter == clonedFilter);
943 } else {
944 CEASSERT(filter != clonedFilter);
945 }
946
947 UnicodeString rules;
948 UnicodeString clonedRules;
949 rules = tr->toRules(rules, FALSE);
950 clonedRules = clonedTR->toRules(clonedRules, FALSE);
951 CEASSERT(rules == clonedRules);
952
953 UnicodeSet sourceSet;
954 UnicodeSet clonedSourceSet;
955 tr->getSourceSet(sourceSet);
956 clonedTR->getSourceSet(clonedSourceSet);
957 CEASSERT(clonedSourceSet == sourceSet);
958
959 UnicodeSet targetSet;
960 UnicodeSet clonedTargetSet;
961 tr->getTargetSet(targetSet);
962 clonedTR->getTargetSet(clonedTargetSet);
963 CEASSERT(targetSet == clonedTargetSet);
964
965 UClassID classID = tr->getDynamicClassID();
966 CEASSERT(classID == clonedTR->getDynamicClassID());
967 CEASSERT(classID != 0);
968
969 delete clonedTR;
970 }
971
972 static const int MyUnicodeFunctorTestClassID = 0;
973 class MyUnicodeFunctorTestClass : public UnicodeFunctor {
974 public:
clone() const975 virtual UnicodeFunctor* clone() const {return NULL;}
getStaticClassID(void)976 static UClassID getStaticClassID(void) {return (UClassID)&MyUnicodeFunctorTestClassID;}
getDynamicClassID(void) const977 virtual UClassID getDynamicClassID(void) const {return getStaticClassID();}
setData(const TransliterationRuleData *)978 virtual void setData(const TransliterationRuleData*) {}
979 };
980
TestUnicodeFunctor()981 void TransliteratorAPITest::TestUnicodeFunctor() {
982 MyUnicodeFunctorTestClass myClass;
983 if (myClass.toMatcher() != NULL) {
984 errln("FAIL: UnicodeFunctor::toMatcher did not return NULL");
985 }
986 if (myClass.toReplacer() != NULL) {
987 errln("FAIL: UnicodeFunctor::toReplacer did not return NULL");
988 }
989 }
990
991
992 #endif /* #if !UCONFIG_NO_TRANSLITERATION */
993