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
6 * Corporation and others. All Rights Reserved.
8 ************************************************************************
9 * Date Name Description
10 * 03/09/2000 Madhu Creation.
11 ************************************************************************/
13 #include "unicode/utypes.h"
15 #if !UCONFIG_NO_TRANSLITERATION
18 #include "unicode/utypes.h"
19 #include "unicode/translit.h"
20 #include "unicode/uniset.h"
24 //---------------------------------------------
26 //---------------------------------------------
29 CompoundTransliteratorTest::runIndexedTest(int32_t index
, UBool exec
,
30 const char* &name
, char* /*par*/) {
32 TESTCASE(0,TestConstruction
);
33 TESTCASE(1,TestCloneEqual
);
34 TESTCASE(2,TestGetCount
);
35 TESTCASE(3,TestGetSetAdoptTransliterator
);
36 TESTCASE(4,TestTransliterate
);
37 default: name
= ""; break;
41 void CompoundTransliteratorTest::TestConstruction(){
42 logln("Testing the construction of the compound Transliterator");
43 UnicodeString names
[]={"Greek-Latin", "Latin-Devanagari", "Devanagari-Latin", "Latin-Greek"};
44 UParseError parseError
;
45 UErrorCode status
=U_ZERO_ERROR
;
46 Transliterator
* t1
=Transliterator::createInstance(names
[0], UTRANS_FORWARD
, parseError
, status
);
47 Transliterator
* t2
=Transliterator::createInstance(names
[1], UTRANS_FORWARD
, parseError
, status
);
48 Transliterator
* t3
=Transliterator::createInstance(names
[2], UTRANS_FORWARD
, parseError
, status
);
49 Transliterator
* t4
=Transliterator::createInstance(names
[3], UTRANS_FORWARD
, parseError
, status
);
50 if(U_FAILURE(status
)){
51 dataerrln("Transliterator construction failed - %s", u_errorName(status
));
56 Transliterator
* transarray1
[]={t1
};
57 Transliterator
* transarray2
[]={t1
, t4
};
58 Transliterator
* transarray3
[]={t4
, t1
, t2
};
59 Transliterator
* transarray4
[]={t1
, t2
, t3
, t4
};
61 Transliterator
** transarray
[4];
62 transarray
[0] = transarray1
;
63 transarray
[1] = transarray2
;
64 transarray
[2] = transarray3
;
65 transarray
[3] = transarray4
;
67 const UnicodeString IDs
[]={
69 names
[0]+";"+names
[3],
70 names
[3]+";"+names
[1]+";"+names
[2],
71 names
[0]+";"+names
[1]+";"+names
[2]+";"+names
[3]
76 status
= U_ZERO_ERROR
;
77 CompoundTransliterator
*cpdtrans
=new CompoundTransliterator(IDs
[i
],parseError
, status
);
78 if (U_FAILURE(status
)) {
79 errln("Construction using CompoundTransliterator(UnicodeString&, Direction, UnicodeFilter*) failed");
83 CompoundTransliterator
*cpdtrans2
=new CompoundTransliterator(transarray
[i
], i
+1);
85 errln("Construction using CompoundTransliterator(Transliterator* const transliterators[], "
86 "int32_t count, UnicodeFilter* adoptedFilter = 0) failed");
89 CompoundTransliterator
*copycpd
=new CompoundTransliterator(*cpdtrans2
);
90 if(copycpd
->getCount() != cpdtrans2
->getCount() || copycpd
->getID() != cpdtrans2
->getID()) {
91 errln("Copy construction failed");
101 /*Test Jitterbug 914 */
102 UErrorCode err
= U_ZERO_ERROR
;
103 CompoundTransliterator
cpdTrans(UnicodeString("Latin-Hangul"),UTRANS_REVERSE
,NULL
,parseError
,err
);
104 UnicodeString newID
=cpdTrans
.getID();
105 if(newID
!=UnicodeString("Hangul-Latin")){
106 errln(UnicodeString("Test for Jitterbug 914 for cpdTrans(UnicodeString(\"Latin-Hangul\"),UTRANS_REVERSE,NULL,err) failed"));
116 void CompoundTransliteratorTest::TestCloneEqual(){
117 logln("Testing the clone() and equality operator functions of Compound Transliterator");
118 UErrorCode status
= U_ZERO_ERROR
;
119 UParseError parseError
;
120 CompoundTransliterator
*ct1
=new CompoundTransliterator("Greek-Latin;Latin-Devanagari",parseError
,status
);
121 if(U_FAILURE(status
)){
122 dataerrln("construction failed - %s", u_errorName(status
));
126 CompoundTransliterator
*ct2
=new CompoundTransliterator("Greek-Latin", parseError
, status
);
127 if(U_FAILURE(status
)){
128 errln("construction failed");
133 CompoundTransliterator
*copyct1
=new CompoundTransliterator(*ct1
);
135 errln("copy construction failed");
138 CompoundTransliterator
*copyct2
=new CompoundTransliterator(*ct2
);
140 errln("copy construction failed");
143 CompoundTransliterator equalct1
=*copyct1
;
144 CompoundTransliterator equalct2
=*copyct2
;
146 if(copyct1
->getID() != ct1
->getID() || copyct2
->getID() != ct2
->getID() ||
147 copyct1
->getCount() != ct1
->getCount() || copyct2
->getCount() != ct2
->getCount() ||
148 copyct2
->getID() == ct1
->getID() || copyct1
->getID() == ct2
->getID() ||
149 copyct2
->getCount() == ct1
->getCount() || copyct1
->getCount() == ct2
->getCount() ){
150 errln("Error: copy constructors failed");
153 if(equalct1
.getID() != ct1
->getID() || equalct2
.getID() != ct2
->getID() ||
154 equalct1
.getID() != copyct1
->getID() || equalct2
.getID() != copyct2
->getID() ||
155 equalct1
.getCount() != ct1
->getCount() || equalct2
.getCount() != ct2
->getCount() ||
156 copyct2
->getID() == ct1
->getID() || copyct1
->getID() == ct2
->getID() ||
157 equalct1
.getCount() != copyct1
->getCount() || equalct2
.getCount() != copyct2
->getCount() ||
158 equalct2
.getCount() == ct1
->getCount() || equalct1
.getCount() == ct2
->getCount() ) {
159 errln("Error: =operator or copy constructor failed");
162 CompoundTransliterator
*clonect1a
=(CompoundTransliterator
*)ct1
->clone();
163 CompoundTransliterator
*clonect1b
=(CompoundTransliterator
*)equalct1
.clone();
164 CompoundTransliterator
*clonect2a
=(CompoundTransliterator
*)ct2
->clone();
165 CompoundTransliterator
*clonect2b
=(CompoundTransliterator
*)copyct2
->clone();
168 if(clonect1a
->getID() != ct1
->getID() || clonect1a
->getCount() != ct1
->getCount() ||
169 clonect1a
->getID() != clonect1b
->getID() || clonect1a
->getCount() != clonect1b
->getCount() ||
170 clonect1a
->getID() != equalct1
.getID() || clonect1a
->getCount() != equalct1
.getCount() ||
171 clonect1a
->getID() != copyct1
->getID() || clonect1a
->getCount() != copyct1
->getCount() ||
173 clonect2b
->getID() != ct2
->getID() || clonect2a
->getCount() != ct2
->getCount() ||
174 clonect2a
->getID() != clonect2b
->getID() || clonect2a
->getCount() != clonect2b
->getCount() ||
175 clonect2a
->getID() != equalct2
.getID() || clonect2a
->getCount() != equalct2
.getCount() ||
176 clonect2b
->getID() != copyct2
->getID() || clonect2b
->getCount() != copyct2
->getCount() ) {
177 errln("Error: clone() failed");
191 void CompoundTransliteratorTest::TestGetCount(){
192 logln("Testing the getCount() API of CompoundTransliterator");
193 UErrorCode status
= U_ZERO_ERROR
;
194 UParseError parseError
;
195 CompoundTransliterator
*ct1
=new CompoundTransliterator("Halfwidth-Fullwidth;Fullwidth-Halfwidth", parseError
, status
);
196 CompoundTransliterator
*ct2
=new CompoundTransliterator("Any-Hex;Hex-Any;Cyrillic-Latin;Latin-Cyrillic", parseError
, status
);
197 CompoundTransliterator
*ct3
=(CompoundTransliterator
*)ct1
;
198 if (U_FAILURE(status
)) {
199 dataerrln("FAILED: CompoundTransliterator constructor failed - %s", u_errorName(status
));
202 CompoundTransliterator
*ct4
=new CompoundTransliterator("Latin-Devanagari", parseError
, status
);
203 CompoundTransliterator
*ct5
=new CompoundTransliterator(*ct4
);
205 if (U_FAILURE(status
)) {
206 errln("FAILED: CompoundTransliterator constructor failed");
209 if(ct1
->getCount() == ct2
->getCount() || ct1
->getCount() != ct3
->getCount() ||
210 ct2
->getCount() == ct3
->getCount() ||
211 ct4
->getCount() != ct5
->getCount() || ct4
->getCount() == ct1
->getCount() ||
212 ct4
->getCount() == ct2
->getCount() || ct4
->getCount() == ct3
->getCount() ||
213 ct5
->getCount() == ct2
->getCount() || ct5
->getCount() == ct3
->getCount() ) {
214 errln("Error: getCount() failed");
217 /* Quick test getTargetSet(), only test that it doesn't die. TODO: a better test. */
219 UnicodeSet
*retUS
= NULL
;
220 retUS
= &ct1
->getTargetSet(ts
);
221 if (retUS
!= &ts
|| ts
.size() == 0) {
222 errln("CompoundTransliterator::getTargetSet() failed.\n");
225 /* Quick test getSourceSet(), only test that it doesn't die. TODO: a better test. */
228 retUS
= &ct1
->getSourceSet(ss
);
229 if (retUS
!= &ss
|| ss
.size() == 0) {
230 errln("CompoundTransliterator::getSourceSet() failed.\n");
239 void CompoundTransliteratorTest::TestGetSetAdoptTransliterator(){
240 logln("Testing the getTransliterator() API of CompoundTransliterator");
241 UnicodeString
ID("Latin-Greek;Greek-Latin;Latin-Devanagari;Devanagari-Latin;Latin-Cyrillic;Cyrillic-Latin;Any-Hex;Hex-Any");
242 UErrorCode status
= U_ZERO_ERROR
;
243 UParseError parseError
;
244 CompoundTransliterator
*ct1
=new CompoundTransliterator(ID
, parseError
, status
);
245 if(U_FAILURE(status
)){
246 dataerrln("CompoundTransliterator construction failed - %s", u_errorName(status
));
249 int32_t count
=ct1
->getCount();
250 UnicodeString
*array
=split(ID
, 0x003b, count
);
252 for(i
=0; i
< count
; i
++){
253 UnicodeString child
= ct1
->getTransliterator(i
).getID();
254 if(child
!= *(array
+i
)){
255 errln("Error getTransliterator() failed: Expected->" + *(array
+i
) + " Got->" + child
);
257 logln("OK: getTransliterator() passed: Expected->" + *(array
+i
) + " Got->" + child
);
262 logln("Testing setTransliterator() API of CompoundTransliterator");
263 UnicodeString
ID2("Hex-Any;Any-Hex;Latin-Cyrillic;Cyrillic-Latin;Halfwidth-Fullwidth;Fullwidth-Halfwidth");
264 array
=split(ID2
, 0x003b, count
);
265 Transliterator
** transarray
=new Transliterator
*[count
];
266 for(i
=0;i
<count
;i
++){
267 transarray
[i
]=Transliterator::createInstance(*(array
+i
), UTRANS_FORWARD
, parseError
, status
);
268 if(U_FAILURE(status
)){
269 errln("Error could not create Transliterator with ID :"+*(array
+i
));
271 logln("The ID for the transltierator created is " + transarray
[i
]->getID());
273 status
= U_ZERO_ERROR
;
276 /*setTransliterator and adoptTransliterator */
278 ct1
->setTransliterators(transarray
, count
);
279 if(ct1
->getCount() != count
|| ct1
->getID() != ID2
){
280 errln((UnicodeString
)"Error: setTransliterators() failed.\n\t Count:- expected->" + count
+ (UnicodeString
)". got->" + ct1
->getCount() +
281 (UnicodeString
)"\n\tID :- expected->" + ID2
+ (UnicodeString
)". got->" + ct1
->getID());
284 logln("OK: setTransliterators() passed");
286 /*UnicodeString temp;
287 for(i=0;i<count-1;i++){
288 temp.append(ct1->getTransliterator(i).getID());
291 temp.append(ct1->getTransliterator(i).getID());
293 errln("Error: setTransliterator() failed. Expected->" + ID2 + "\nGot->" + temp);
296 logln("OK: setTransliterator() passed");
298 logln("Testing adoptTransliterator() API of CompoundTransliterator");
299 UnicodeString
ID3("Latin-Katakana");
300 Transliterator
**transarray2
=(Transliterator
**)uprv_malloc(sizeof(Transliterator
*)*1);
301 transarray2
[0] = Transliterator::createInstance(ID3
,UTRANS_FORWARD
,parseError
,status
);
302 if (transarray2
[0] != 0) {
303 ct1
->adoptTransliterators(transarray2
, 1);
305 if(ct1
->getCount() != 1 || ct1
->getID() != ID3
){
306 errln((UnicodeString
)"Error: adoptTransliterators() failed.\n\t Count:- expected->1" + (UnicodeString
)". got->" + ct1
->getCount() +
307 (UnicodeString
)"\n\tID :- expected->" + ID3
+ (UnicodeString
)". got->" + ct1
->getID());
310 logln("OK: adoptTranslterator() passed");
313 for(i
=0;i
<count
;i
++){
314 delete transarray
[i
];
321 * Splits a UnicodeString
323 UnicodeString
* CompoundTransliteratorTest::split(const UnicodeString
& str
, UChar seperator
, int32_t& count
) {
328 for(i
=0; i
<str
.length(); i
++){
329 if(str
.charAt(i
) == seperator
)
333 UnicodeString
* result
= new UnicodeString
[count
];
336 for (i
= 0; i
< str
.length(); ++i
) {
337 if (str
.charAt(i
) == seperator
) {
338 str
.extractBetween(last
, i
, result
[current
]);
343 str
.extractBetween(last
, i
, result
[current
]);
346 void CompoundTransliteratorTest::TestTransliterate(){
347 logln("Testing the handleTransliterate() API of CompoundTransliterator");
348 UErrorCode status
= U_ZERO_ERROR
;
349 UParseError parseError
;
350 CompoundTransliterator
*ct1
=new CompoundTransliterator("Any-Hex;Hex-Any",parseError
, status
);
351 if(U_FAILURE(status
)){
352 errln("CompoundTransliterator construction failed");
355 // handleTransliterate is a protected method that was erroneously made
356 // public. It is not public API that needs to be tested.
357 UnicodeString
s("abcabc");
359 UTransPosition index
= { 0, 0, 0, 0 };
360 UnicodeString
rsource2(s
);
361 UnicodeString expectedResult
=s
;
362 ct1
->handleTransliterate(rsource2
, index
, FALSE
);
363 expectAux(ct1
->getID() + ":String, index(0,0,0), incremental=FALSE", rsource2
+ "->" + rsource2
, rsource2
==expectedResult
, expectedResult
);
364 UTransPosition _index
= {1,3,2,3};
365 uprv_memcpy(&index
, &_index
, sizeof(index
));
366 UnicodeString
rsource3(s
);
367 ct1
->handleTransliterate(rsource3
, index
, TRUE
);
368 expectAux(ct1
->getID() + ":String, index(1,2,3), incremental=TRUE", rsource3
+ "->" + rsource3
, rsource3
==expectedResult
, expectedResult
);
372 UnicodeString Data
[]={
373 //ID, input string, transliterated string
374 "Any-Hex;Hex-Any;Any-Hex", "hello", UnicodeString("\\u0068\\u0065\\u006C\\u006C\\u006F", ""),
375 "Any-Hex;Hex-Any", "hello! How are you?", "hello! How are you?",
376 //"Devanagari-Latin;Latin-Devanagari", CharsToUnicodeString("\\u092D\\u0948'\\u0930'\\u0935"), CharsToUnicodeString("\\u092D\\u0948\\u0930\\u0935"), // quotes lost
377 "Latin-Cyrillic;Cyrillic-Latin", "a'b'k'd'e'f'g'h'i'j'Shch'shch'zh'h", "a'b'k'd'e'f'g'h'i'j'Shch'shch'zh'h", //"abkdefghijShchshchzhh",
378 "Latin-Greek;Greek-Latin", "ABGabgAKLMN", "ABGabgAKLMN",
379 //"Latin-Arabic;Arabic-Latin", "Ad'r'a'b'i'k'dh'dd'gh", "Adrabikdhddgh",
380 "Hiragana-Katakana", CharsToUnicodeString("\\u3041\\u308f\\u3099\\u306e\\u304b\\u3092\\u3099"),
381 CharsToUnicodeString("\\u30A1\\u30f7\\u30ce\\u30ab\\u30fa"),
382 "Hiragana-Katakana;Katakana-Hiragana", CharsToUnicodeString("\\u3041\\u308f\\u3099\\u306e\\u304b\\u3051"),
383 CharsToUnicodeString("\\u3041\\u308f\\u3099\\u306e\\u304b\\u3051"),
384 "Katakana-Hiragana;Hiragana-Katakana", CharsToUnicodeString("\\u30A1\\u30f7\\u30ce\\u30f5\\u30f6"),
385 CharsToUnicodeString("\\u30A1\\u30f7\\u30ce\\u30ab\\u30b1"),
386 "Latin-Katakana;Katakana-Latin", CharsToUnicodeString("vavivuvevohuzizuzonyinyunyasesuzezu"),
387 CharsToUnicodeString("vavivuvevohuzizuzonyinyunyasesuzezu"),
390 for(i
=0; i
<UPRV_LENGTHOF(Data
); i
=i
+3){
391 UErrorCode status
= U_ZERO_ERROR
;
393 CompoundTransliterator
*ct2
=new CompoundTransliterator(Data
[i
+0], parseError
, status
);
394 if(U_FAILURE(status
)){
395 dataerrln("CompoundTransliterator construction failed for " + Data
[i
+0] + " - " + u_errorName(status
));
397 expect(*ct2
, Data
[i
+1], Data
[i
+2]);
406 //======================================================================
408 //======================================================================
409 void CompoundTransliteratorTest::expect(const CompoundTransliterator
& t
,
410 const UnicodeString
& source
,
411 const UnicodeString
& expectedResult
) {
413 UnicodeString
rsource(source
);
414 t
.transliterate(rsource
);
415 expectAux(t
.getID() + ":Replaceable", source
+ "->" + rsource
, rsource
==expectedResult
, expectedResult
);
417 // Test transliterate (incremental) transliteration --
419 rsource
.append(source
);
420 UTransPosition index
;
421 index
.contextStart
=0;
422 index
.contextLimit
= source
.length();
424 index
.limit
= source
.length();
425 UErrorCode ec
= U_ZERO_ERROR
;
426 t
.transliterate(rsource
, index
, ec
);
427 t
.finishTransliteration(rsource
,index
);
428 expectAux(t
.getID() + ":handleTransliterate ", source
+ "->" + rsource
, rsource
==expectedResult
, expectedResult
);
432 void CompoundTransliteratorTest::expectAux(const UnicodeString
& tag
,
433 const UnicodeString
& summary
, UBool pass
,
434 const UnicodeString
& expectedResult
) {
436 logln(UnicodeString("(")+tag
+") " + prettify(summary
));
438 errln(UnicodeString("FAIL: (")+tag
+") "
440 + ", expected " + prettify(expectedResult
));
444 #endif /* #if !UCONFIG_NO_TRANSLITERATION */