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 }else {
523 log = s + " => ";
524 t->finishTransliteration(s, index);
525 }
526 // Show the start index '{' and the cursor '|'
527 displayOutput(s, Data[i+1], log, index);
528 }
529
530 delete t;
531 }
532
TestKeyboardTransliterator2()533 void TransliteratorAPITest::TestKeyboardTransliterator2(){
534 UnicodeString Data[]={
535 //insertion, buffer, index[START], index[LIMIT], index[CURSOR]
536 //data for Any-Hex
537 "abc", UnicodeString("Initial String: add-\\u0061\\u0062\\u0063-", ""), "19", "20", "20",
538 "a", UnicodeString("In\\u0069\\u0061tial String: add-\\u0061\\u0062\\u0063-", ""), "2", "3", "2" ,
539 "b", UnicodeString("\\u0062In\\u0069\\u0061tial String: add-\\u0061\\u0062\\u0063-", ""), "0", "0", "0" ,
540 "", UnicodeString("\\u0062In\\u0069\\u0061tial String: add-\\u0061\\u0062\\u0063-", ""), "0", "0", "0" ,
541 //data for Latin-Devanagiri
542 CharsToUnicodeString("a\\u0304"), CharsToUnicodeString("Hindi -\\u0906-"), "6", "7", "6",
543 CharsToUnicodeString("ma\\u0304"), CharsToUnicodeString("Hindi -\\u0906\\u092E\\u093E-"), "7", "8", "7",
544 CharsToUnicodeString("ra\\u0304"), CharsToUnicodeString("Hi\\u0930\\u093Endi -\\u0906\\u092E\\u093E-"),"1", "2", "2",
545 CharsToUnicodeString(""), CharsToUnicodeString("Hi\\u0930\\u093Endi -\\u0906\\u092E\\u093E-"),"1", "2", "2"
546 //data for contracted-Expanded
547 // CharsToUnicodeString("\\u00C1"), CharsToUnicodeString("Ad\\u0041\\u0301d here:"), "1", "2", "1" ,
548 // CharsToUnicodeString("\\u00C0"), CharsToUnicodeString("Ad\\u0041\\u0301d here:\\u0041\\u0300"), "11", "11", "11",
549 // "", CharsToUnicodeString("Ad\\u0041\\u0301d here:\\u0041\\u0300"), "11", "11", "11",
550 };
551 Transliterator *t;
552 UnicodeString rs;
553 UnicodeString dataStr;
554 logln("Testing transliterate(Replaceable, int32_t, UnicodeString, UErrorCode)");
555 UErrorCode status = U_ZERO_ERROR;
556 UParseError parseError;
557 rs="Initial String: add--";
558 t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status);
559 if(t == 0)
560 dataerrln("FAIL : construction - %s", u_errorName(status));
561 else {
562 keyboardAux(t, Data, rs, 0, 20);
563 delete t;
564 }
565
566 rs="Hindi --";
567 t=Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseError, status);
568 if(t == 0)
569 dataerrln("FAIL : construction - %s", u_errorName(status));
570 else
571 keyboardAux(t, Data, rs, 20, 40);
572
573
574 // rs="Add here:";
575 // t=Transliterator::createInstance("Contracted-Expanded");
576 // keyboardAux(t, Data, rs, 35, 55);
577
578
579 delete t;
580 }
581
TestKeyboardTransliterator3()582 void TransliteratorAPITest::TestKeyboardTransliterator3(){
583 UnicodeString s="This is the main string";
584 UnicodeString Data[] = {
585 "0", "0", "0", "This is the main string",
586 "1", "3", "2", UnicodeString("Th\\u0069s is the main string", ""),
587 "20", "21", "20", UnicodeString("Th\\u0069s is the mai\\u006E string", "")
588 };
589
590 UErrorCode status=U_ZERO_ERROR;
591 UParseError parseError;
592 UTransPosition index={0, 0, 0, 0};
593 logln("Testing transliterate(Replaceable, int32_t, UErrorCode)");
594 Transliterator *t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status);
595 if(t == 0 || U_FAILURE(status)) {
596 errln("Error creating transliterator %s", u_errorName(status));
597 delete t;
598 return;
599 }
600 for(uint32_t i=0; i<UPRV_LENGTHOF(Data); i=i+4){
601 UnicodeString log;
602 index.contextStart=getInt(Data[i+0]);
603 index.contextLimit=index.limit=getInt(Data[i+1]);
604 index.start=getInt(Data[i+2]);
605 t->transliterate(s, index, status);
606 if(U_FAILURE(status)){
607 errln("FAIL: " + t->getID()+ ".transliterate(Replaceable, int32_t[], UErrorCode)-->" + (UnicodeString)u_errorName(status));
608 continue;
609 }
610 t->finishTransliteration(s, index);
611 log = s + " => ";
612 // Show the start index '{' and the cursor '|'
613 displayOutput(s, Data[i+3], log, index);
614 }
615
616 delete t;
617 }
TestNullTransliterator()618 void TransliteratorAPITest::TestNullTransliterator(){
619 UErrorCode status=U_ZERO_ERROR;
620 UnicodeString s("Transliterate using null transliterator");
621 Transliterator *nullTrans=Transliterator::createInstance("Any-Null", UTRANS_FORWARD, status);
622 int32_t transLimit;
623 int32_t start=0;
624 int32_t limit=s.length();
625 UnicodeString replaceable=s;
626 transLimit=nullTrans->transliterate(replaceable, start, limit);
627 if(transLimit != limit){
628 errln("ERROR: NullTransliterator->transliterate() failed");
629 }
630 doTest((UnicodeString)"nulTrans->transliterate", replaceable, s);
631 replaceable.remove();
632 replaceable.append(s);
633 UTransPosition index;
634 index.contextStart =start;
635 index.contextLimit = limit;
636 index.start = 0;
637 index.limit = limit;
638 nullTrans->finishTransliteration(replaceable, index);
639 if(index.start != limit){
640 errln("ERROR: NullTransliterator->handleTransliterate() failed");
641 }
642 doTest((UnicodeString)"NullTransliterator->handleTransliterate", replaceable, s);
643 callEverything(nullTrans, __LINE__);
644 delete nullTrans;
645
646
647 }
TestRegisterUnregister()648 void TransliteratorAPITest::TestRegisterUnregister(){
649
650 UErrorCode status=U_ZERO_ERROR;
651 /* Make sure it doesn't exist */
652 if (Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD, status) != NULL) {
653 errln("FAIL: TestA-TestB already registered\n");
654 return;
655 }
656 /* Check inverse too
657 if (Transliterator::createInstance("TestA-TestB",
658 (UTransDirection)UTRANS_REVERSE) != NULL) {
659 errln("FAIL: TestA-TestB inverse already registered\n");
660 return;
661 }
662 */
663 status =U_ZERO_ERROR;
664
665 /* Create it */
666 UParseError parseError;
667 Transliterator *t = Transliterator::createFromRules("TestA-TestB",
668 "a<>b",
669 UTRANS_FORWARD, parseError,
670 status);
671 /* Register it */
672 Transliterator::registerInstance(t);
673
674 /* Now check again -- should exist now*/
675 Transliterator *s = Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD, status);
676 if (s == NULL) {
677 errln("FAIL: TestA-TestB not registered\n");
678 return;
679 }
680 callEverything(s, __LINE__);
681 callEverything(t, __LINE__);
682 delete s;
683
684 /* Check inverse too
685 s = Transliterator::createInstance("TestA-TestB",
686 (UTransDirection)UTRANS_REVERSE);
687 if (s == NULL) {
688 errln("FAIL: TestA-TestB inverse not registered\n");
689 return;
690 }
691 delete s;
692 */
693
694 /*unregister the instance*/
695 Transliterator::unregister("TestA-TestB");
696 /* now Make sure it doesn't exist */
697 if (Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD, status) != NULL) {
698 errln("FAIL: TestA-TestB isn't unregistered\n");
699 return;
700 }
701
702 }
703
704
705 int gTestFilter1ClassID = 0;
706 int gTestFilter2ClassID = 0;
707 int gTestFilter3ClassID = 0;
708
709 /**
710 * Used by TestFiltering().
711 */
712 class TestFilter1 : public UnicodeFilter {
getDynamicClassID() const713 UClassID getDynamicClassID()const { return &gTestFilter1ClassID; }
clone() const714 virtual UnicodeFunctor* clone() const {
715 return new TestFilter1(*this);
716 }
contains(UChar32 c) const717 virtual UBool contains(UChar32 c) const {
718 if(c==0x63 || c==0x61 || c==0x43 || c==0x41)
719 return FALSE;
720 else
721 return TRUE;
722 }
723 // Stubs
toPattern(UnicodeString & result,UBool) const724 virtual UnicodeString& toPattern(UnicodeString& result,
725 UBool /*escapeUnprintable*/) const {
726 return result;
727 }
matchesIndexValue(uint8_t) const728 virtual UBool matchesIndexValue(uint8_t /*v*/) const {
729 return FALSE;
730 }
addMatchSetTo(UnicodeSet &) const731 virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {}
732 };
733 class TestFilter2 : public UnicodeFilter {
getDynamicClassID() const734 UClassID getDynamicClassID()const { return &gTestFilter2ClassID; }
clone() const735 virtual UnicodeFunctor* clone() const {
736 return new TestFilter2(*this);
737 }
contains(UChar32 c) const738 virtual UBool contains(UChar32 c) const {
739 if(c==0x65 || c==0x6c)
740 return FALSE;
741 else
742 return TRUE;
743 }
744 // Stubs
toPattern(UnicodeString & result,UBool) const745 virtual UnicodeString& toPattern(UnicodeString& result,
746 UBool /*escapeUnprintable*/) const {
747 return result;
748 }
matchesIndexValue(uint8_t) const749 virtual UBool matchesIndexValue(uint8_t /*v*/) const {
750 return FALSE;
751 }
addMatchSetTo(UnicodeSet &) const752 virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {}
753 };
754 class TestFilter3 : public UnicodeFilter {
getDynamicClassID() const755 UClassID getDynamicClassID()const { return &gTestFilter3ClassID; }
clone() const756 virtual UnicodeFunctor* clone() const {
757 return new TestFilter3(*this);
758 }
contains(UChar32 c) const759 virtual UBool contains(UChar32 c) const {
760 if(c==0x6f || c==0x77)
761 return FALSE;
762 else
763 return TRUE;
764 }
765 // Stubs
toPattern(UnicodeString & result,UBool) const766 virtual UnicodeString& toPattern(UnicodeString& result,
767 UBool /*escapeUnprintable*/) const {
768 return result;
769 }
matchesIndexValue(uint8_t) const770 virtual UBool matchesIndexValue(uint8_t /*v*/) const {
771 return FALSE;
772 }
addMatchSetTo(UnicodeSet &) const773 virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {}
774 };
775
776
TestGetAdoptFilter()777 void TransliteratorAPITest::TestGetAdoptFilter(){
778 UErrorCode status = U_ZERO_ERROR;
779 UParseError parseError;
780 Transliterator *t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status);
781 if(t == 0 || U_FAILURE(status)) {
782 errln("Error creating transliterator %s", u_errorName(status));
783 delete t;
784 return;
785 }
786 const UnicodeFilter *u=t->getFilter();
787 if(u != NULL){
788 errln("FAIL: getFilter failed. Didn't return null when the transliterator used no filtering");
789 delete t;
790 return;
791 }
792
793 UnicodeString got, temp, message;
794 UnicodeString data="ABCabcbbCBa";
795 temp = data;
796 t->transliterate(temp);
797 t->adoptFilter(new TestFilter1);
798
799 got = data;
800 t->transliterate(got);
801 UnicodeString exp=UnicodeString("A\\u0042Ca\\u0062c\\u0062\\u0062C\\u0042a", "");
802 message="transliteration after adoptFilter(a,A,c,C) ";
803 doTest(message, got, exp);
804
805 logln("Testing round trip");
806 t->adoptFilter((UnicodeFilter*)u);
807 if(t->getFilter() == NULL)
808 logln("OK: adoptFilter and getFilter round trip worked");
809 else
810 errln("FAIL: adoptFilter or getFilter round trip failed");
811
812 got = data;
813 t->transliterate(got);
814 exp=UnicodeString("\\u0041\\u0042\\u0043\\u0061\\u0062\\u0063\\u0062\\u0062\\u0043\\u0042\\u0061", "");
815 message="transliteration after adopting null filter";
816 doTest(message, got, exp);
817 message="adoptFilter round trip";
818 doTest("adoptFilter round trip", got, temp);
819
820 t->adoptFilter(new TestFilter2);
821 callEverything(t, __LINE__);
822 data="heelloe";
823 exp=UnicodeString("\\u0068eell\\u006Fe", "");
824 got = data;
825 t->transliterate(got);
826 message="transliteration using (e,l) filter";
827 doTest("transliteration using (e,l) filter", got, exp);
828
829 data="are well";
830 exp=UnicodeString("\\u0061\\u0072e\\u0020\\u0077ell", "");
831 got = data;
832 t->transliterate(got);
833 doTest(message, got, exp);
834
835 t->adoptFilter(new TestFilter3);
836 data="ho, wow!";
837 exp=UnicodeString("\\u0068o\\u002C\\u0020wow\\u0021", "");
838 got = data;
839 t->transliterate(got);
840 message="transliteration using (o,w) filter";
841 doTest("transliteration using (o,w) filter", got, exp);
842
843 data="owl";
844 exp=UnicodeString("ow\\u006C", "");
845 got = data;
846 t->transliterate(got);
847 doTest("transliteration using (o,w) filter", got, exp);
848
849 delete t;
850
851 }
852
853
854
keyboardAux(Transliterator * t,UnicodeString DATA[],UnicodeString & s,int32_t begin,int32_t end)855 void TransliteratorAPITest::keyboardAux(Transliterator *t, UnicodeString DATA[], UnicodeString& s, int32_t begin, int32_t end) {
856 UTransPosition index={0, 0, 0, 0};
857 UErrorCode status=U_ZERO_ERROR;
858 for (int32_t i=begin; i<end; i=i+5) {
859 UnicodeString log;
860 if (DATA[i+0] != "") {
861 log = s + " + " + DATA[i] + " -> ";
862 index.contextStart=getInt(DATA[i+2]);
863 index.contextLimit=index.limit=getInt(DATA[i+3]);
864 index.start=getInt(DATA[i+4]);
865 t->transliterate(s, index, DATA[i+0], status);
866 if(U_FAILURE(status)){
867 errln("FAIL: " + t->getID()+ ".transliterate(Replaceable, int32_t[], UnicodeString, UErrorCode)-->" + (UnicodeString)u_errorName(status));
868 continue;
869 }
870 log = s + " => ";
871 t->finishTransliteration(s, index);
872 }
873 // Show the start index '{' and the cursor '|'
874 displayOutput(s, DATA[i+1], log, index);
875
876 }
877 }
878
displayOutput(const UnicodeString & got,const UnicodeString & expected,UnicodeString & log,UTransPosition & 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);
887 log.append(a).
888 append((UChar)0x7b/*{*/).
889 append(b).
890 append((UChar)0x7c/*|*/).
891 append(c).
892 append((UChar)0x7c).
893 append(d).
894 append((UChar)0x7d/*}*/).
895 append(e);
896 if (got == expected)
897 logln("OK:" + prettify(log));
898 else
899 errln("FAIL: " + prettify(log) + ", expected " + prettify(expected));
900 }
901
902
903 /*Internal Functions used*/
doTest(const UnicodeString & message,const UnicodeString & result,const UnicodeString & expected)904 void TransliteratorAPITest::doTest(const UnicodeString& message, const UnicodeString& result, const UnicodeString& expected){
905 if (prettify(result) == prettify(expected))
906 logln((UnicodeString)"Ok: " + prettify(message) + " passed \"" + prettify(expected) + "\"");
907 else
908 dataerrln((UnicodeString)"FAIL:" + message + " failed Got-->" + prettify(result)+ ", Expected--> " + prettify(expected) );
909 }
910
911
912 //
913 // callEverything call all of the const (non-destructive) methods on a
914 // transliterator, just to verify that they don't fail in some
915 // destructive way.
916 //
917 #define CEASSERT(a) {if (!(a)) { \
918 errln("FAIL at line %d from line %d: %s", __LINE__, line, #a); return; }}
919
callEverything(const Transliterator * tr,int line)920 void TransliteratorAPITest::callEverything(const Transliterator *tr, int line) {
921 Transliterator *clonedTR = tr->clone();
922 CEASSERT(clonedTR != NULL);
923
924 int32_t maxcl = tr->getMaximumContextLength();
925 CEASSERT(clonedTR->getMaximumContextLength() == maxcl);
926
927 UnicodeString id;
928 UnicodeString clonedId;
929 id = tr->getID();
930 clonedId = clonedTR->getID();
931 CEASSERT(id == clonedId);
932
933 const UnicodeFilter *filter = tr->getFilter();
934 const UnicodeFilter *clonedFilter = clonedTR->getFilter();
935 if (filter == NULL || clonedFilter == NULL) {
936 // If one filter is NULL they better both be NULL.
937 CEASSERT(filter == clonedFilter);
938 } else {
939 CEASSERT(filter != clonedFilter);
940 }
941
942 UnicodeString rules;
943 UnicodeString clonedRules;
944 rules = tr->toRules(rules, FALSE);
945 clonedRules = clonedTR->toRules(clonedRules, FALSE);
946 CEASSERT(rules == clonedRules);
947
948 UnicodeSet sourceSet;
949 UnicodeSet clonedSourceSet;
950 tr->getSourceSet(sourceSet);
951 clonedTR->getSourceSet(clonedSourceSet);
952 CEASSERT(clonedSourceSet == sourceSet);
953
954 UnicodeSet targetSet;
955 UnicodeSet clonedTargetSet;
956 tr->getTargetSet(targetSet);
957 clonedTR->getTargetSet(clonedTargetSet);
958 CEASSERT(targetSet == clonedTargetSet);
959
960 UClassID classID = tr->getDynamicClassID();
961 CEASSERT(classID == clonedTR->getDynamicClassID());
962 CEASSERT(classID != 0);
963
964 delete clonedTR;
965 }
966
967 static const int MyUnicodeFunctorTestClassID = 0;
968 class MyUnicodeFunctorTestClass : public UnicodeFunctor {
969 public:
clone() const970 virtual UnicodeFunctor* clone() const {return NULL;}
getStaticClassID(void)971 static UClassID getStaticClassID(void) {return (UClassID)&MyUnicodeFunctorTestClassID;}
getDynamicClassID(void) const972 virtual UClassID getDynamicClassID(void) const {return getStaticClassID();};
setData(const TransliterationRuleData *)973 virtual void setData(const TransliterationRuleData*) {}
974 };
975
TestUnicodeFunctor()976 void TransliteratorAPITest::TestUnicodeFunctor() {
977 MyUnicodeFunctorTestClass myClass;
978 if (myClass.toMatcher() != NULL) {
979 errln("FAIL: UnicodeFunctor::toMatcher did not return NULL");
980 }
981 if (myClass.toReplacer() != NULL) {
982 errln("FAIL: UnicodeFunctor::toReplacer did not return NULL");
983 }
984 }
985
986
987 #endif /* #if !UCONFIG_NO_TRANSLITERATION */
988