1 /********************************************************************
3 * Copyright (c) 1997-2004, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
8 #include "unicode/unistr.h"
9 #include "unicode/uchar.h"
10 #include "unicode/ustring.h"
11 #include "unicode/locid.h"
12 #include "unicode/ucnv.h"
17 #include "unicode/ustream.h"
19 #if U_IOSTREAM_SOURCE >= 199711
22 #elif U_IOSTREAM_SOURCE >= 198506
28 #define LENGTHOF(array) (int32_t)((sizeof(array)/sizeof((array)[0])))
30 UnicodeStringTest::~UnicodeStringTest() {}
32 void UnicodeStringTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char *par
)
34 if (exec
) logln("TestSuite UnicodeStringTest: ");
37 name
= "StringCaseTest";
39 logln("StringCaseTest---"); logln("");
44 case 1: name
= "TestBasicManipulation"; if (exec
) TestBasicManipulation(); break;
45 case 2: name
= "TestCompare"; if (exec
) TestCompare(); break;
46 case 3: name
= "TestExtract"; if (exec
) TestExtract(); break;
47 case 4: name
= "TestRemoveReplace"; if (exec
) TestRemoveReplace(); break;
48 case 5: name
= "TestSearching"; if (exec
) TestSearching(); break;
49 case 6: name
= "TestSpacePadding"; if (exec
) TestSpacePadding(); break;
50 case 7: name
= "TestPrefixAndSuffix"; if (exec
) TestPrefixAndSuffix(); break;
51 case 8: name
= "TestFindAndReplace"; if (exec
) TestFindAndReplace(); break;
52 case 9: name
= "TestBogus"; if (exec
) TestBogus(); break;
53 case 10: name
= "TestReverse"; if (exec
) TestReverse(); break;
54 case 11: name
= "TestMiscellaneous"; if (exec
) TestMiscellaneous(); break;
55 case 12: name
= "TestStackAllocation"; if (exec
) TestStackAllocation(); break;
56 case 13: name
= "TestUnescape"; if (exec
) TestUnescape(); break;
57 case 14: name
= "TestCountChar32"; if (exec
) TestCountChar32(); break;
58 case 15: name
= "TestStringEnumeration"; if (exec
) TestStringEnumeration(); break;
59 case 16: name
= "TestCharString"; if (exec
) TestCharString(); break;
61 default: name
= ""; break; //needed to end loop
66 UnicodeStringTest::TestBasicManipulation()
68 UnicodeString
test1("Now is the time for all men to come swiftly to the aid of the party.\n");
69 UnicodeString expectedValue
;
72 c
=(UnicodeString
*)test1
.clone();
73 test1
.insert(24, "good ");
74 expectedValue
= "Now is the time for all good men to come swiftly to the aid of the party.\n";
75 if (test1
!= expectedValue
)
76 errln("insert() failed: expected \"" + expectedValue
+ "\"\n,got \"" + test1
+ "\"");
78 c
->insert(24, "good ");
79 if(*c
!= expectedValue
) {
80 errln("clone()->insert() failed: expected \"" + expectedValue
+ "\"\n,got \"" + *c
+ "\"");
85 expectedValue
= "Now is the time for all good men to come to the aid of the party.\n";
86 if (test1
!= expectedValue
)
87 errln("remove() failed: expected \"" + expectedValue
+ "\"\n,got \"" + test1
+ "\"");
89 test1
.replace(58, 6, "ir country");
90 expectedValue
= "Now is the time for all good men to come to the aid of their country.\n";
91 if (test1
!= expectedValue
)
92 errln("replace() failed: expected \"" + expectedValue
+ "\"\n,got \"" + test1
+ "\"");
95 test1
.extract(0, 15, temp
);
97 UnicodeString
test2(temp
, 15);
99 expectedValue
= "Now is the time";
100 if (test2
!= expectedValue
)
101 errln("extract() failed: expected \"" + expectedValue
+ "\"\n,got \"" + test2
+ "\"");
103 test2
+= " for me to go!\n";
104 expectedValue
= "Now is the time for me to go!\n";
105 if (test2
!= expectedValue
)
106 errln("operator+=() failed: expected \"" + expectedValue
+ "\"\n,got \"" + test2
+ "\"");
108 if (test1
.length() != 70)
109 errln("length() failed: expected 70, got " + test1
.length());
110 if (test2
.length() != 30)
111 errln("length() failed: expected 30, got " + test2
.length());
114 test3
.append((UChar32
)0x20402);
115 if(test3
!= CharsToUnicodeString("\\uD841\\uDC02")){
116 errln((UnicodeString
)"append failed for UChar32, expected \"\\\\ud841\\\\udc02\", got " + prettify(test3
));
118 if(test3
.length() != 2){
119 errln("append or length failed for UChar32, expected 2, got " + test3
.length());
121 test3
.append((UChar32
)0x0074);
122 if(test3
!= CharsToUnicodeString("\\uD841\\uDC02t")){
123 errln((UnicodeString
)"append failed for UChar32, expected \"\\\\uD841\\\\uDC02t\", got " + prettify(test3
));
125 if(test3
.length() != 3){
126 errln((UnicodeString
)"append or length failed for UChar32, expected 2, got " + test3
.length());
129 // test some UChar32 overloads
130 if( test3
.setTo((UChar32
)0x10330).length() != 2 ||
131 test3
.insert(0, (UChar32
)0x20100).length() != 4 ||
132 test3
.replace(2, 2, (UChar32
)0xe0061).length() != 4 ||
133 (test3
= (UChar32
)0x14001).length() != 2
135 errln((UnicodeString
)"simple UChar32 overloads for replace, insert, setTo or = failed");
139 // test moveIndex32()
140 UnicodeString s
=UNICODE_STRING("\\U0002f999\\U0001d15f\\u00c4\\u1ed0", 32).unescape();
143 s
.moveIndex32(2, -1)!=0 ||
144 s
.moveIndex32(2, 1)!=4 ||
145 s
.moveIndex32(2, 2)!=5 ||
146 s
.moveIndex32(5, -2)!=2 ||
147 s
.moveIndex32(0, -1)!=0 ||
148 s
.moveIndex32(6, 1)!=6
150 errln("UnicodeString::moveIndex32() failed");
153 if(s
.getChar32Start(1)!=0 || s
.getChar32Start(2)!=2) {
154 errln("UnicodeString::getChar32Start() failed");
157 if(s
.getChar32Limit(1)!=2 || s
.getChar32Limit(2)!=2) {
158 errln("UnicodeString::getChar32Limit() failed");
163 // test new 2.2 constructors and setTo function that parallel Java's substring function.
164 UnicodeString
src("Hello folks how are you?");
165 UnicodeString
target1("how are you?");
166 if (target1
!= UnicodeString(src
, 12)) {
167 errln("UnicodeString(const UnicodeString&, int32_t) failed");
169 UnicodeString
target2("folks");
170 if (target2
!= UnicodeString(src
, 6, 5)) {
171 errln("UnicodeString(const UnicodeString&, int32_t, int32_t) failed");
173 if (target1
!= target2
.setTo(src
, 12)) {
174 errln("UnicodeString::setTo(const UnicodeString&, int32_t) failed");
179 // op+ is new in ICU 2.8
180 UnicodeString s
=UnicodeString("abc", "")+UnicodeString("def", "")+UnicodeString("ghi", "");
181 if(s
!=UnicodeString("abcdefghi", "")) {
182 errln("operator+(UniStr, UniStr) failed");
187 // tests for Jitterbug 2360
188 // verify that APIs with source pointer + length accept length == -1
189 // mostly test only where modified, only few functions did not already do this
190 if(UnicodeString("abc", -1, "")!=UnicodeString("abc", "")) {
191 errln("UnicodeString(codepageData, dataLength, codepage) does not work with dataLength==-1");
194 UChar buffer
[10]={ 0x61, 0x62, 0x20ac, 0xd900, 0xdc05, 0, 0x62, 0xffff, 0xdbff, 0xdfff };
195 UnicodeString s
, t(buffer
, -1, LENGTHOF(buffer
));
197 if(s
.setTo(buffer
, -1, LENGTHOF(buffer
)).length()!=u_strlen(buffer
)) {
198 errln("UnicodeString.setTo(buffer, length, capacity) does not work with length==-1");
200 if(t
.length()!=u_strlen(buffer
)) {
201 errln("UnicodeString(buffer, length, capacity) does not work with length==-1");
204 if(0!=s
.caseCompare(buffer
, -1, U_FOLD_CASE_DEFAULT
)) {
205 errln("UnicodeString.caseCompare(const UChar *, length, options) does not work with length==-1");
207 if(0!=s
.caseCompare(0, s
.length(), buffer
, U_FOLD_CASE_DEFAULT
)) {
208 errln("UnicodeString.caseCompare(start, _length, const UChar *, options) does not work");
211 buffer
[u_strlen(buffer
)]=0xe4;
212 UnicodeString
u(buffer
, -1, LENGTHOF(buffer
));
213 if(s
.setTo(buffer
, -1, LENGTHOF(buffer
)).length()!=LENGTHOF(buffer
)) {
214 errln("UnicodeString.setTo(buffer without NUL, length, capacity) does not work with length==-1");
216 if(u
.length()!=LENGTHOF(buffer
)) {
217 errln("UnicodeString(buffer without NUL, length, capacity) does not work with length==-1");
220 static const char cs
[]={ 0x61, (char)0xe4, (char)0x85, 0 };
222 UErrorCode errorCode
=U_ZERO_ERROR
;
224 cnv
=ucnv_open("ISO-8859-1", &errorCode
);
225 UnicodeString
v(cs
, -1, cnv
, errorCode
);
227 if(v
!=UnicodeString("a\\xe4\\x85").unescape()) {
228 errln("UnicodeString(const char *, length, cnv, errorCode) does not work with length==-1");
234 UnicodeStringTest::TestCompare()
236 UnicodeString
test1("this is a test");
237 UnicodeString
test2("this is a test");
238 UnicodeString
test3("this is a test of the emergency broadcast system");
239 UnicodeString
test4("never say, \"this is a test\"!!");
241 UnicodeString
test5((UChar
)0x5000);
242 UnicodeString
test6((UChar
)0x5100);
244 UChar uniChars
[] = { 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73,
245 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0 };
246 char chars
[] = "this is a test";
248 // test operator== and operator!=
249 if (test1
!= test2
|| test1
== test3
|| test1
== test4
)
250 errln("operator== or operator!= failed");
252 // test operator> and operator<
253 if (test1
> test2
|| test1
< test2
|| !(test1
< test3
) || !(test1
> test4
) ||
256 errln("operator> or operator< failed");
259 // test operator>= and operator<=
260 if (!(test1
>= test2
) || !(test1
<= test2
) || !(test1
<= test3
) || !(test1
>= test4
))
261 errln("operator>= or operator<= failed");
263 // test compare(UnicodeString)
264 if (test1
.compare(test2
) != 0 || test1
.compare(test3
) >= 0 || test1
.compare(test4
) <= 0)
265 errln("compare(UnicodeString) failed");
267 //test compare(offset, length, UnicodeString)
268 if(test1
.compare(0, 14, test2
) != 0 ||
269 test3
.compare(0, 14, test2
) != 0 ||
270 test4
.compare(12, 14, test2
) != 0 ||
271 test3
.compare(0, 18, test1
) <=0 )
272 errln("compare(offset, length, UnicodeString) failes");
274 // test compare(UChar*)
275 if (test2
.compare(uniChars
) != 0 || test3
.compare(uniChars
) <= 0 || test4
.compare(uniChars
) >= 0)
276 errln("compare(UChar*) failed");
278 // test compare(char*)
279 if (test2
.compare(chars
) != 0 || test3
.compare(chars
) <= 0 || test4
.compare(chars
) >= 0)
280 errln("compare(char*) failed");
282 // test compare(UChar*, length)
283 if (test1
.compare(uniChars
, 4) <= 0 || test1
.compare(uniChars
, 4) <= 0)
284 errln("compare(UChar*, length) failed");
286 // test compare(thisOffset, thisLength, that, thatOffset, thatLength)
287 if (test1
.compare(0, 14, test2
, 0, 14) != 0
288 || test1
.compare(0, 14, test3
, 0, 14) != 0
289 || test1
.compare(0, 14, test4
, 12, 14) != 0)
290 errln("1. compare(thisOffset, thisLength, that, thatOffset, thatLength) failed");
292 if (test1
.compare(10, 4, test2
, 0, 4) >= 0
293 || test1
.compare(10, 4, test3
, 22, 9) <= 0
294 || test1
.compare(10, 4, test4
, 22, 4) != 0)
295 errln("2. compare(thisOffset, thisLength, that, thatOffset, thatLength) failed");
297 // test compareBetween
298 if (test1
.compareBetween(0, 14, test2
, 0, 14) != 0 || test1
.compareBetween(0, 14, test3
, 0, 14) != 0
299 || test1
.compareBetween(0, 14, test4
, 12, 26) != 0)
300 errln("compareBetween failed");
302 if (test1
.compareBetween(10, 14, test2
, 0, 4) >= 0 || test1
.compareBetween(10, 14, test3
, 22, 31) <= 0
303 || test1
.compareBetween(10, 14, test4
, 22, 26) != 0)
304 errln("compareBetween failed");
306 // test compare() etc. with strings that share a buffer but are not equal
307 test2
=test1
; // share the buffer, length() too large for the stackBuffer
308 test2
.truncate(1); // change only the length, not the buffer
309 if( test1
==test2
|| test1
<=test2
||
310 test1
.compare(test2
)<=0 ||
311 test1
.compareCodePointOrder(test2
)<=0 ||
312 test1
.compareCodePointOrder(0, INT32_MAX
, test2
)<=0 ||
313 test1
.compareCodePointOrder(0, INT32_MAX
, test2
, 0, INT32_MAX
)<=0 ||
314 test1
.compareCodePointOrderBetween(0, INT32_MAX
, test2
, 0, INT32_MAX
)<=0 ||
315 test1
.caseCompare(test2
, U_FOLD_CASE_DEFAULT
)<=0
317 errln("UnicodeStrings that share a buffer but have different lengths compare as equal");
320 /* test compareCodePointOrder() */
322 /* these strings are in ascending order */
323 static const UChar strings
[][4]={
324 { 0x61, 0 }, /* U+0061 */
325 { 0x20ac, 0xd801, 0 }, /* U+20ac U+d801 */
326 { 0x20ac, 0xd800, 0xdc00, 0 }, /* U+20ac U+10000 */
327 { 0xd800, 0 }, /* U+d800 */
328 { 0xd800, 0xff61, 0 }, /* U+d800 U+ff61 */
329 { 0xdfff, 0 }, /* U+dfff */
330 { 0xff61, 0xdfff, 0 }, /* U+ff61 U+dfff */
331 { 0xff61, 0xd800, 0xdc02, 0 }, /* U+ff61 U+10002 */
332 { 0xd800, 0xdc02, 0 }, /* U+10002 */
333 { 0xd84d, 0xdc56, 0 } /* U+23456 */
335 UnicodeString u
[20]; // must be at least as long as strings[]
338 for(i
=0; i
<(int32_t)(sizeof(strings
)/sizeof(strings
[0])); ++i
) {
339 u
[i
]=UnicodeString(TRUE
, strings
[i
], -1);
342 for(i
=0; i
<(int32_t)(sizeof(strings
)/sizeof(strings
[0])-1); ++i
) {
343 if(u
[i
].compareCodePointOrder(u
[i
+1])>=0 || u
[i
].compareCodePointOrder(0, INT32_MAX
, u
[i
+1].getBuffer())>=0) {
344 errln("error: UnicodeString::compareCodePointOrder() fails for string %d and the following one\n", i
);
349 /* test caseCompare() */
352 _mixed
[]= { 0x61, 0x42, 0x131, 0x3a3, 0xdf, 0x130, 0x49, 0xfb03, 0xd93f, 0xdfff, 0 },
353 _otherDefault
[]= { 0x41, 0x62, 0x131, 0x3c3, 0x73, 0x53, 0x69, 0x307, 0x69, 0x46, 0x66, 0x49, 0xd93f, 0xdfff, 0 },
354 _otherExcludeSpecialI
[]={ 0x41, 0x62, 0x131, 0x3c3, 0x53, 0x73, 0x69, 0x131, 0x66, 0x46, 0x69, 0xd93f, 0xdfff, 0 },
355 _different
[]= { 0x41, 0x62, 0x131, 0x3c3, 0x73, 0x53, 0x130, 0x49, 0x46, 0x66, 0x49, 0xd93f, 0xdffd, 0 };
358 mixed(TRUE
, _mixed
, -1),
359 otherDefault(TRUE
, _otherDefault
, -1),
360 otherExcludeSpecialI(TRUE
, _otherExcludeSpecialI
, -1),
361 different(TRUE
, _different
, -1);
365 /* test caseCompare() */
366 result
=mixed
.caseCompare(otherDefault
, U_FOLD_CASE_DEFAULT
);
367 if(result
!=0 || 0!=mixed
.caseCompareBetween(0, INT32_MAX
, otherDefault
, 0, INT32_MAX
, U_FOLD_CASE_DEFAULT
)) {
368 errln("error: mixed.caseCompare(other, default)=%ld instead of 0\n", result
);
370 result
=mixed
.caseCompare(otherExcludeSpecialI
, U_FOLD_CASE_EXCLUDE_SPECIAL_I
);
372 errln("error: mixed.caseCompare(otherExcludeSpecialI, U_FOLD_CASE_EXCLUDE_SPECIAL_I)=%ld instead of 0\n", result
);
374 result
=mixed
.caseCompare(otherDefault
, U_FOLD_CASE_EXCLUDE_SPECIAL_I
);
375 if(result
==0 || 0==mixed
.caseCompareBetween(0, INT32_MAX
, otherDefault
, 0, INT32_MAX
, U_FOLD_CASE_EXCLUDE_SPECIAL_I
)) {
376 errln("error: mixed.caseCompare(other, U_FOLD_CASE_EXCLUDE_SPECIAL_I)=0 instead of !=0\n");
379 /* test caseCompare() */
380 result
=mixed
.caseCompare(different
, U_FOLD_CASE_DEFAULT
);
382 errln("error: mixed.caseCompare(different, default)=%ld instead of positive\n", result
);
385 /* test caseCompare() - include the folded sharp s (U+00df) with different lengths */
386 result
=mixed
.caseCompare(1, 4, different
, 1, 5, U_FOLD_CASE_DEFAULT
);
387 if(result
!=0 || 0!=mixed
.caseCompareBetween(1, 5, different
, 1, 6, U_FOLD_CASE_DEFAULT
)) {
388 errln("error: mixed.caseCompare(mixed, 1, 4, different, 1, 5, default)=%ld instead of 0\n", result
);
391 /* test caseCompare() - stop in the middle of the sharp s (U+00df) */
392 result
=mixed
.caseCompare(1, 4, different
, 1, 4, U_FOLD_CASE_DEFAULT
);
394 errln("error: mixed.caseCompare(1, 4, different, 1, 4, default)=%ld instead of positive\n", result
);
398 // test that srcLength=-1 is handled in functions that
399 // take input const UChar */int32_t srcLength (j785)
401 static const UChar u
[]={ 0x61, 0x308, 0x62, 0 };
402 UnicodeString s
=UNICODE_STRING("a\\u0308b", 8).unescape();
404 if(s
.compare(u
, -1)!=0 || s
.compare(0, 999, u
, 0, -1)!=0) {
405 errln("error UnicodeString::compare(..., const UChar *, srcLength=-1) does not work");
408 if(s
.compareCodePointOrder(u
, -1)!=0 || s
.compareCodePointOrder(0, 999, u
, 0, -1)!=0) {
409 errln("error UnicodeString::compareCodePointOrder(..., const UChar *, srcLength=-1, ...) does not work");
412 if(s
.caseCompare(u
, -1, U_FOLD_CASE_DEFAULT
)!=0 || s
.caseCompare(0, 999, u
, 0, -1, U_FOLD_CASE_DEFAULT
)!=0) {
413 errln("error UnicodeString::caseCompare(..., const UChar *, srcLength=-1, ...) does not work");
416 if(s
.indexOf(u
, 1, -1, 0, 999)!=1 || s
.indexOf(u
+1, -1, 0, 999)!=1 || s
.indexOf(u
+1, -1, 0)!=1) {
417 errln("error UnicodeString::indexOf(const UChar *, srcLength=-1, ...) does not work");
420 if(s
.lastIndexOf(u
, 1, -1, 0, 999)!=1 || s
.lastIndexOf(u
+1, -1, 0, 999)!=1 || s
.lastIndexOf(u
+1, -1, 0)!=1) {
421 errln("error UnicodeString::lastIndexOf(const UChar *, srcLength=-1, ...) does not work");
424 UnicodeString s2
, s3
;
425 s2
.replace(0, 0, u
+1, -1);
426 s3
.replace(0, 0, u
, 1, -1);
427 if(s
.compare(1, 999, s2
)!=0 || s2
!=s3
) {
428 errln("error UnicodeString::replace(..., const UChar *, srcLength=-1, ...) does not work");
434 UnicodeStringTest::TestExtract()
436 UnicodeString
test1("Now is the time for all good men to come to the aid of their country.", "");
438 UChar test3
[13] = {1, 2, 3, 4, 5, 6, 7, 8, 8, 10, 11, 12, 13};
439 char test4
[13] = {1, 2, 3, 4, 5, 6, 7, 8, 8, 10, 11, 12, 13};
441 char test6
[13] = {1, 2, 3, 4, 5, 6, 7, 8, 8, 10, 11, 12, 13};
443 test1
.extract(11, 12, test2
);
444 test1
.extract(11, 12, test3
);
445 if (test1
.extract(11, 12, test4
) != 12 || test4
[12] != 0) {
446 errln("UnicodeString.extract(char *) failed to return the correct size of destination buffer.");
449 // test proper pinning in extractBetween()
450 test1
.extractBetween(-3, 7, test5
);
451 if(test5
!=UNICODE_STRING("Now is ", 7)) {
452 errln("UnicodeString.extractBetween(-3, 7) did not pin properly.");
455 test1
.extractBetween(11, 23, test5
);
456 if (test1
.extract(60, 71, test6
) != 9) {
457 errln("UnicodeString.extract() failed to return the correct size of destination buffer for end of buffer.");
459 if (test1
.extract(11, 12, test6
) != 12) {
460 errln("UnicodeString.extract() failed to return the correct size of destination buffer.");
463 // convert test4 back to Unicode for comparison
464 UnicodeString
test4b(test4
, 12);
466 if (test1
.extract(11, 12, (char *)NULL
) != 12) {
467 errln("UnicodeString.extract(NULL) failed to return the correct size of destination buffer.");
469 if (test1
.extract(11, -1, test6
) != 0) {
470 errln("UnicodeString.extract(-1) failed to stop reading the string.");
473 for (int32_t i
= 0; i
< 12; i
++) {
474 if (test1
.charAt((int32_t)(11 + i
)) != test2
.charAt(i
)) {
475 errln(UnicodeString("extracting into a UnicodeString failed at position ") + i
);
478 if (test1
.charAt((int32_t)(11 + i
)) != test3
[i
]) {
479 errln(UnicodeString("extracting into an array of UChar failed at position ") + i
);
482 if (((char)test1
.charAt((int32_t)(11 + i
))) != test4b
.charAt(i
)) {
483 errln(UnicodeString("extracting into an array of char failed at position ") + i
);
486 if (test1
.charAt((int32_t)(11 + i
)) != test5
.charAt(i
)) {
487 errln(UnicodeString("extracting with extractBetween failed at position ") + i
);
492 // test preflighting and overflows with invariant conversion
493 if (test1
.extract(0, 10, (char *)NULL
, "") != 10) {
494 errln("UnicodeString.extract(0, 10, (char *)NULL, \"\") != 10");
497 test4
[2] = (char)0xff;
498 if (test1
.extract(0, 10, test4
, 2, "") != 10) {
499 errln("UnicodeString.extract(0, 10, test4, 2, \"\") != 10");
501 if (test4
[2] != (char)0xff) {
502 errln("UnicodeString.extract(0, 10, test4, 2, \"\") overwrote test4[2]");
506 // test new, NUL-terminating extract() function
507 UnicodeString
s("terminate", "");
509 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
510 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5
512 UErrorCode errorCode
;
515 errorCode
=U_ZERO_ERROR
;
516 length
=s
.extract((UChar
*)NULL
, 0, errorCode
);
517 if(errorCode
!=U_BUFFER_OVERFLOW_ERROR
|| length
!=s
.length()) {
518 errln("UnicodeString.extract(NULL, 0)==%d (%s) expected %d (U_BUFFER_OVERFLOW_ERROR)", length
, s
.length(), u_errorName(errorCode
));
521 errorCode
=U_ZERO_ERROR
;
522 length
=s
.extract(dest
, s
.length()-1, errorCode
);
523 if(errorCode
!=U_BUFFER_OVERFLOW_ERROR
|| length
!=s
.length()) {
524 errln("UnicodeString.extract(dest too short)==%d (%s) expected %d (U_BUFFER_OVERFLOW_ERROR)",
525 length
, u_errorName(errorCode
), s
.length());
528 errorCode
=U_ZERO_ERROR
;
529 length
=s
.extract(dest
, s
.length(), errorCode
);
530 if(errorCode
!=U_STRING_NOT_TERMINATED_WARNING
|| length
!=s
.length()) {
531 errln("UnicodeString.extract(dest just right without NUL)==%d (%s) expected %d (U_STRING_NOT_TERMINATED_WARNING)",
532 length
, u_errorName(errorCode
), s
.length());
534 if(dest
[length
-1]!=s
[length
-1] || dest
[length
]!=0xa5) {
535 errln("UnicodeString.extract(dest just right without NUL) did not extract the string correctly");
538 errorCode
=U_ZERO_ERROR
;
539 length
=s
.extract(dest
, s
.length()+1, errorCode
);
540 if(errorCode
!=U_ZERO_ERROR
|| length
!=s
.length()) {
541 errln("UnicodeString.extract(dest large enough)==%d (%s) expected %d (U_ZERO_ERROR)",
542 length
, u_errorName(errorCode
), s
.length());
544 if(dest
[length
-1]!=s
[length
-1] || dest
[length
]!=0 || dest
[length
+1]!=0xa5) {
545 errln("UnicodeString.extract(dest large enough) did not extract the string correctly");
550 // test new UConverter extract() and constructor
551 UnicodeString s
=UNICODE_STRING("\\U0002f999\\U0001d15f\\u00c4\\u1ed0", 32).unescape();
553 static const char expect
[]={
554 (char)0xf0, (char)0xaf, (char)0xa6, (char)0x99,
555 (char)0xf0, (char)0x9d, (char)0x85, (char)0x9f,
556 (char)0xc3, (char)0x84,
557 (char)0xe1, (char)0xbb, (char)0x90
559 UErrorCode errorCode
=U_ZERO_ERROR
;
560 UConverter
*cnv
=ucnv_open("UTF-8", &errorCode
);
563 if(U_SUCCESS(errorCode
)) {
565 if( (length
=s
.extract(NULL
, 0, cnv
, errorCode
))!=13 ||
566 errorCode
!=U_BUFFER_OVERFLOW_ERROR
568 errln("UnicodeString::extract(NULL, UConverter) preflighting failed (length=%ld, %s)",
569 length
, u_errorName(errorCode
));
571 errorCode
=U_ZERO_ERROR
;
572 if( (length
=s
.extract(buffer
, 2, cnv
, errorCode
))!=13 ||
573 errorCode
!=U_BUFFER_OVERFLOW_ERROR
575 errln("UnicodeString::extract(too small, UConverter) preflighting failed (length=%ld, %s)",
576 length
, u_errorName(errorCode
));
580 errorCode
=U_ZERO_ERROR
;
581 if( s
.extract(NULL
, 2, cnv
, errorCode
)==13 || U_SUCCESS(errorCode
)) {
582 errln("UnicodeString::extract(UConverter) succeeded with an illegal destination");
584 errorCode
=U_ILLEGAL_ARGUMENT_ERROR
;
585 if( s
.extract(NULL
, 0, cnv
, errorCode
)==13 || U_SUCCESS(errorCode
)) {
586 errln("UnicodeString::extract(UConverter) succeeded with a previous error code");
588 errorCode
=U_ZERO_ERROR
;
591 if( (length
=s
.extract(buffer
, sizeof(buffer
), cnv
, errorCode
))!=13 ||
592 uprv_memcmp(buffer
, expect
, 13)!=0 ||
596 errln("UnicodeString::extract(UConverter) conversion failed (length=%ld, %s)",
597 length
, u_errorName(errorCode
));
599 // Test again with just the converter name.
600 if( (length
=s
.extract(0, s
.length(), buffer
, sizeof(buffer
), "UTF-8"))!=13 ||
601 uprv_memcmp(buffer
, expect
, 13)!=0 ||
605 errln("UnicodeString::extract(\"UTF-8\") conversion failed (length=%ld, %s)",
606 length
, u_errorName(errorCode
));
609 // try the constructor
610 UnicodeString
t(expect
, sizeof(expect
), cnv
, errorCode
);
611 if(U_FAILURE(errorCode
) || s
!=t
) {
612 errln("UnicodeString(UConverter) conversion failed (%s)",
613 u_errorName(errorCode
));
622 UnicodeStringTest::TestRemoveReplace()
624 UnicodeString
test1("The rain in Spain stays mainly on the plain");
625 UnicodeString
test2("eat SPAMburgers!");
626 UChar test3
[] = { 0x53, 0x50, 0x41, 0x4d, 0x4d, 0 };
627 char test4
[] = "SPAM";
628 UnicodeString
& test5
= test1
;
630 test1
.replace(4, 4, test2
, 4, 4);
631 test1
.replace(12, 5, test3
, 4);
633 test1
.replace(17, 4, test3
);
634 test1
.replace(23, 4, test4
);
635 test1
.replaceBetween(37, 42, test2
, 4, 8);
637 if (test1
!= "The SPAM in SPAM SPAMs SPAMly on the SPAM")
638 errln("One of the replace methods failed:\n"
639 " expected \"The SPAM in SPAM SPAMs SPAMly on the SPAM\",\n"
640 " got \"" + test1
+ "\"");
643 test1
.removeBetween(26, 28);
645 if (test1
!= "The SPAM in SPAM SPAM SPAM on the SPAM")
646 errln("One of the remove methods failed:\n"
647 " expected \"The SPAM in SPAM SPAM SPAM on the SPAM\",\n"
648 " got \"" + test1
+ "\"");
650 for (int32_t i
= 0; i
< test1
.length(); i
++) {
651 if (test5
[i
] != 0x53 && test5
[i
] != 0x50 && test5
[i
] != 0x41 && test5
[i
] != 0x4d && test5
[i
] != 0x20) {
652 test1
.setCharAt(i
, 0x78);
656 if (test1
!= "xxx SPAM xx SPAM SPAM SPAM xx xxx SPAM")
657 errln("One of the remove methods failed:\n"
658 " expected \"xxx SPAM xx SPAM SPAM SPAM xx xxx SPAM\",\n"
659 " got \"" + test1
+ "\"");
662 if (test1
.length() != 0)
663 errln("Remove() failed: expected empty string, got \"" + test1
+ "\"");
667 UnicodeStringTest::TestSearching()
669 UnicodeString
test1("test test ttest tetest testesteststt");
670 UnicodeString
test2("test");
671 UChar testChar
= 0x74;
673 UChar32 testChar32
= 0x20402;
676 0xd841, 0xdc02, 0x0071, 0xdc02, 0xd841, 0x0071, 0xd841, 0xdc02,
678 // 8 9 10 11 12 13 14 15
679 0x0071, 0x0072, 0xd841, 0xdc02, 0x0071, 0xd841, 0xdc02, 0x0071,
682 0xdc02, 0xd841, 0x0073, 0x0000
684 UnicodeString
test3(testData
);
685 UnicodeString
test4(testChar32
);
687 uint16_t occurrences
= 0;
688 int32_t startPos
= 0;
690 startPos
!= -1 && startPos
< test1
.length();
691 (startPos
= test1
.indexOf(test2
, startPos
)) != -1 ? (++occurrences
, startPos
+= 4) : 0)
693 if (occurrences
!= 6)
694 errln("indexOf failed: expected to find 6 occurrences, found " + occurrences
);
696 for ( occurrences
= 0, startPos
= 10;
697 startPos
!= -1 && startPos
< test1
.length();
698 (startPos
= test1
.indexOf(test2
, startPos
)) != -1 ? (++occurrences
, startPos
+= 4) : 0)
700 if (occurrences
!= 4)
701 errln("indexOf with starting offset failed: expected to find 4 occurrences, found " + occurrences
);
704 for ( occurrences
= 0, startPos
= 5;
705 startPos
!= -1 && startPos
< test1
.length();
706 (startPos
= test1
.indexOf(test2
, startPos
, endPos
- startPos
)) != -1 ? (++occurrences
, startPos
+= 4) : 0)
708 if (occurrences
!= 4)
709 errln("indexOf with starting and ending offsets failed: expected to find 4 occurrences, found " + occurrences
);
711 //using UChar32 string
712 for ( startPos
=0, occurrences
=0;
713 startPos
!= -1 && startPos
< test3
.length();
714 (startPos
= test3
.indexOf(test4
, startPos
)) != -1 ? (++occurrences
, startPos
+= 2) : 0)
716 if (occurrences
!= 4)
717 errln((UnicodeString
)"indexOf failed: expected to find 4 occurrences, found " + occurrences
);
719 for ( startPos
=10, occurrences
=0;
720 startPos
!= -1 && startPos
< test3
.length();
721 (startPos
= test3
.indexOf(test4
, startPos
)) != -1 ? (++occurrences
, startPos
+= 2) : 0)
723 if (occurrences
!= 2)
724 errln("indexOf failed: expected to find 2 occurrences, found " + occurrences
);
727 for ( occurrences
= 0, startPos
= 0;
728 startPos
!= -1 && startPos
< test1
.length();
729 (startPos
= test1
.indexOf(testChar
, startPos
)) != -1 ? (++occurrences
, startPos
+= 1) : 0)
731 if (occurrences
!= 16)
732 errln("indexOf with character failed: expected to find 16 occurrences, found " + occurrences
);
734 for ( occurrences
= 0, startPos
= 10;
735 startPos
!= -1 && startPos
< test1
.length();
736 (startPos
= test1
.indexOf(testChar
, startPos
)) != -1 ? (++occurrences
, startPos
+= 1) : 0)
738 if (occurrences
!= 12)
739 errln("indexOf with character & start offset failed: expected to find 12 occurrences, found " + occurrences
);
741 for ( occurrences
= 0, startPos
= 5, endPos
= 28;
742 startPos
!= -1 && startPos
< test1
.length();
743 (startPos
= test1
.indexOf(testChar
, startPos
, endPos
- startPos
)) != -1 ? (++occurrences
, startPos
+= 1) : 0)
745 if (occurrences
!= 10)
746 errln("indexOf with character & start & end offsets failed: expected to find 10 occurrences, found " + occurrences
);
748 //testing for UChar32
749 UnicodeString subString
;
750 for( occurrences
=0, startPos
=0; startPos
< test3
.length(); startPos
+=1){
751 subString
.append(test3
, startPos
, test3
.length());
752 if(subString
.indexOf(testChar32
) != -1 ){
757 if (occurrences
!= 14)
758 errln((UnicodeString
)"indexOf failed: expected to find 14 occurrences, found " + occurrences
);
760 for ( occurrences
= 0, startPos
= 0;
761 startPos
!= -1 && startPos
< test3
.length();
762 (startPos
= test3
.indexOf(testChar32
, startPos
)) != -1 ? (++occurrences
, startPos
+= 1) : 0)
764 if (occurrences
!= 4)
765 errln((UnicodeString
)"indexOf failed: expected to find 4 occurrences, found " + occurrences
);
767 endPos
=test3
.length();
768 for ( occurrences
= 0, startPos
= 5;
769 startPos
!= -1 && startPos
< test3
.length();
770 (startPos
= test3
.indexOf(testChar32
, startPos
, endPos
- startPos
)) != -1 ? (++occurrences
, startPos
+= 1) : 0)
772 if (occurrences
!= 3)
773 errln((UnicodeString
)"indexOf with character & start & end offsets failed: expected to find 2 occurrences, found " + occurrences
);
776 if(test1
.lastIndexOf(test2
)!=29) {
777 errln("test1.lastIndexOf(test2)!=29");
780 if(test1
.lastIndexOf(test2
, 15)!=29 || test1
.lastIndexOf(test2
, 29)!=29 || test1
.lastIndexOf(test2
, 30)!=-1) {
781 errln("test1.lastIndexOf(test2, start) failed");
784 for ( occurrences
= 0, startPos
= 32;
786 (startPos
= test1
.lastIndexOf(test2
, 5, startPos
- 5)) != -1 ? ++occurrences
: 0)
788 if (occurrences
!= 4)
789 errln("lastIndexOf with starting and ending offsets failed: expected to find 4 occurrences, found " + occurrences
);
791 for ( occurrences
= 0, startPos
= 32;
793 (startPos
= test1
.lastIndexOf(testChar
, 5, startPos
- 5)) != -1 ? ++occurrences
: 0)
795 if (occurrences
!= 11)
796 errln("lastIndexOf with character & start & end offsets failed: expected to find 11 occurrences, found " + occurrences
);
799 startPos
=test3
.length();
800 for ( occurrences
= 0;
802 (startPos
= test3
.lastIndexOf(testChar32
, 5, startPos
- 5)) != -1 ? ++occurrences
: 0)
804 if (occurrences
!= 3)
805 errln((UnicodeString
)"lastIndexOf with character & start & end offsets failed: expected to find 3 occurrences, found " + occurrences
);
808 for ( occurrences
= 0, endPos
= test3
.length(); endPos
> 0; endPos
-= 1){
810 subString
.append(test3
, 0, endPos
);
811 if(subString
.lastIndexOf(testChar32
) != -1 ){
815 if (occurrences
!= 18)
816 errln((UnicodeString
)"indexOf failed: expected to find 18 occurrences, found " + occurrences
);
819 // test that indexOf(UChar32) and lastIndexOf(UChar32)
820 // do not find surrogate code points when they are part of matched pairs
821 // (= part of supplementary code points)
823 if(test3
.indexOf((UChar32
)0xd841) != 4 || test3
.indexOf((UChar32
)0xdc02) != 3) {
824 errln("error: UnicodeString::indexOf(UChar32 surrogate) finds a partial supplementary code point");
826 if( UnicodeString(test3
, 0, 17).lastIndexOf((UChar
)0xd841, 0) != 4 ||
827 UnicodeString(test3
, 0, 17).lastIndexOf((UChar32
)0xd841, 2) != 4 ||
828 test3
.lastIndexOf((UChar32
)0xd841, 0, 17) != 4 || test3
.lastIndexOf((UChar32
)0xdc02, 0, 17) != 16
830 errln("error: UnicodeString::lastIndexOf(UChar32 surrogate) finds a partial supplementary code point");
835 UnicodeStringTest::TestSpacePadding()
837 UnicodeString
test1("hello");
838 UnicodeString
test2(" there");
839 UnicodeString
test3("Hi! How ya doin'? Beautiful day, isn't it?");
842 UnicodeString expectedValue
;
844 returnVal
= test1
.padLeading(15);
845 expectedValue
= " hello";
846 if (returnVal
== FALSE
|| test1
!= expectedValue
)
847 errln("padLeading() failed: expected \"" + expectedValue
+ "\", got \"" + test1
+ "\".");
849 returnVal
= test2
.padTrailing(15);
850 expectedValue
= " there ";
851 if (returnVal
== FALSE
|| test2
!= expectedValue
)
852 errln("padTrailing() failed: expected \"" + expectedValue
+ "\", got \"" + test2
+ "\".");
854 expectedValue
= test3
;
855 returnVal
= test3
.padTrailing(15);
856 if (returnVal
== TRUE
|| test3
!= expectedValue
)
857 errln("padTrailing() failed: expected \"" + expectedValue
+ "\", got \"" + test3
+ "\".");
859 expectedValue
= "hello";
860 test4
.setTo(test1
).trim();
862 if (test4
!= expectedValue
|| test1
== expectedValue
|| test4
!= expectedValue
)
863 errln("trim(UnicodeString&) failed");
866 if (test1
!= expectedValue
)
867 errln("trim() failed: expected \"" + expectedValue
+ "\", got \"" + test1
+ "\".");
870 expectedValue
= "there";
871 if (test2
!= expectedValue
)
872 errln("trim() failed: expected \"" + expectedValue
+ "\", got \"" + test2
+ "\".");
875 expectedValue
= "Hi! How ya doin'? Beautiful day, isn't it?";
876 if (test3
!= expectedValue
)
877 errln("trim() failed: expected \"" + expectedValue
+ "\", got \"" + test3
+ "\".");
879 returnVal
= test1
.truncate(15);
880 expectedValue
= "hello";
881 if (returnVal
== TRUE
|| test1
!= expectedValue
)
882 errln("truncate() failed: expected \"" + expectedValue
+ "\", got \"" + test1
+ "\".");
884 returnVal
= test2
.truncate(15);
885 expectedValue
= "there";
886 if (returnVal
== TRUE
|| test2
!= expectedValue
)
887 errln("truncate() failed: expected \"" + expectedValue
+ "\", got \"" + test2
+ "\".");
889 returnVal
= test3
.truncate(15);
890 expectedValue
= "Hi! How ya doi";
891 if (returnVal
== FALSE
|| test3
!= expectedValue
)
892 errln("truncate() failed: expected \"" + expectedValue
+ "\", got \"" + test3
+ "\".");
896 UnicodeStringTest::TestPrefixAndSuffix()
898 UnicodeString
test1("Now is the time for all good men to come to the aid of their country.");
899 UnicodeString
test2("Now");
900 UnicodeString
test3("country.");
901 UnicodeString
test4("count");
903 if (!test1
.startsWith(test2
) || !test1
.startsWith(test2
, 0, test2
.length())) {
904 errln("startsWith() failed: \"" + test2
+ "\" should be a prefix of \"" + test1
+ "\".");
907 if (test1
.startsWith(test3
) ||
908 test1
.startsWith(test3
.getBuffer(), test3
.length()) ||
909 test1
.startsWith(test3
.getTerminatedBuffer(), 0, -1)
911 errln("startsWith() failed: \"" + test3
+ "\" shouldn't be a prefix of \"" + test1
+ "\".");
914 if (test1
.endsWith(test2
)) {
915 errln("endsWith() failed: \"" + test2
+ "\" shouldn't be a suffix of \"" + test1
+ "\".");
918 if (!test1
.endsWith(test3
)) {
919 errln("endsWith(test3) failed: \"" + test3
+ "\" should be a suffix of \"" + test1
+ "\".");
921 if (!test1
.endsWith(test3
, 0, INT32_MAX
)) {
922 errln("endsWith(test3, 0, INT32_MAX) failed: \"" + test3
+ "\" should be a suffix of \"" + test1
+ "\".");
925 if(!test1
.endsWith(test3
.getBuffer(), test3
.length())) {
926 errln("endsWith(test3.getBuffer(), test3.length()) failed: \"" + test3
+ "\" should be a suffix of \"" + test1
+ "\".");
928 if(!test1
.endsWith(test3
.getTerminatedBuffer(), 0, -1)) {
929 errln("endsWith(test3.getTerminatedBuffer(), 0, -1) failed: \"" + test3
+ "\" should be a suffix of \"" + test1
+ "\".");
932 if (!test3
.startsWith(test4
)) {
933 errln("endsWith(test4) failed: \"" + test4
+ "\" should be a prefix of \"" + test3
+ "\".");
936 if (test4
.startsWith(test3
)) {
937 errln("startsWith(test3) failed: \"" + test3
+ "\" shouldn't be a prefix of \"" + test4
+ "\".");
942 UnicodeStringTest::TestFindAndReplace()
944 UnicodeString
test1("One potato, two potato, three potato, four\n");
945 UnicodeString
test2("potato");
946 UnicodeString
test3("MISSISSIPPI");
948 UnicodeString expectedValue
;
950 test1
.findAndReplace(test2
, test3
);
951 expectedValue
= "One MISSISSIPPI, two MISSISSIPPI, three MISSISSIPPI, four\n";
952 if (test1
!= expectedValue
)
953 errln("findAndReplace failed: expected \"" + expectedValue
+ "\", got \"" + test1
+ "\".");
954 test1
.findAndReplace(2, 32, test3
, test2
);
955 expectedValue
= "One potato, two potato, three MISSISSIPPI, four\n";
956 if (test1
!= expectedValue
)
957 errln("findAndReplace failed: expected \"" + expectedValue
+ "\", got \"" + test1
+ "\".");
961 UnicodeStringTest::TestReverse()
963 UnicodeString
test("backwards words say to used I");
972 if (test
!= "I used to say words backwards")
973 errln("reverse() failed: Expected \"I used to say words backwards\",\n got \""
976 test
=UNICODE_STRING("\\U0002f999\\U0001d15f\\u00c4\\u1ed0", 32).unescape();
978 if(test
.char32At(0)!=0x1ed0 || test
.char32At(1)!=0xc4 || test
.char32At(2)!=0x1d15f || test
.char32At(4)!=0x2f999) {
979 errln("reverse() failed with supplementary characters");
984 UnicodeStringTest::TestMiscellaneous()
986 UnicodeString
test1("This is a test");
987 UnicodeString
test2("This is a test");
988 UnicodeString
test3("Me too!");
990 // test getBuffer(minCapacity) and releaseBuffer()
991 test1
=UnicodeString(); // make sure that it starts with its stackBuffer
992 UChar
*p
=test1
.getBuffer(20);
993 if(test1
.getCapacity()<20) {
994 errln("UnicodeString::getBuffer(20).getCapacity()<20");
997 test1
.append((UChar
)7); // must not be able to modify the string here
998 test1
.setCharAt(3, 7);
1000 if( test1
.length()!=0 ||
1001 test1
.charAt(0)!=0xffff || test1
.charAt(3)!=0xffff ||
1002 test1
.getBuffer(10)!=0 || test1
.getBuffer()!=0
1004 errln("UnicodeString::getBuffer(minCapacity) allows read or write access to the UnicodeString");
1010 test1
.releaseBuffer(3);
1011 test1
.append((UChar
)4);
1013 if(test1
.length()!=4 || test1
.charAt(0)!=1 || test1
.charAt(1)!=2 || test1
.charAt(2)!=3 || test1
.charAt(3)!=4) {
1014 errln("UnicodeString::releaseBuffer(newLength) does not properly reallow access to the UnicodeString");
1017 // test releaseBuffer() without getBuffer(minCapacity) - must not have any effect
1018 test1
.releaseBuffer(1);
1019 if(test1
.length()!=4 || test1
.charAt(0)!=1 || test1
.charAt(1)!=2 || test1
.charAt(2)!=3 || test1
.charAt(3)!=4) {
1020 errln("UnicodeString::releaseBuffer(newLength) without getBuffer(minCapacity) changed the UnicodeString");
1023 // test getBuffer(const)
1024 const UChar
*q
=test1
.getBuffer(), *r
=test1
.getBuffer();
1025 if( test1
.length()!=4 ||
1026 q
[0]!=1 || q
[1]!=2 || q
[2]!=3 || q
[3]!=4 ||
1027 r
[0]!=1 || r
[1]!=2 || r
[2]!=3 || r
[3]!=4
1029 errln("UnicodeString::getBuffer(const) does not return a usable buffer pointer");
1032 // test releaseBuffer() with a NUL-terminated buffer
1033 test1
.getBuffer(20)[2]=0;
1034 test1
.releaseBuffer(); // implicit -1
1035 if(test1
.length()!=2 || test1
.charAt(0)!=1 || test1
.charAt(1) !=2) {
1036 errln("UnicodeString::releaseBuffer(-1) does not properly set the length of the UnicodeString");
1039 // test releaseBuffer() with a non-NUL-terminated buffer
1040 p
=test1
.getBuffer(256);
1041 for(int32_t i
=0; i
<test1
.getCapacity(); ++i
) {
1042 p
[i
]=(UChar
)1; // fill the buffer with all non-NUL code units
1044 test1
.releaseBuffer(); // implicit -1
1045 if(test1
.length()!=test1
.getCapacity() || test1
.charAt(1)!=1 || test1
.charAt(100)!=1 || test1
.charAt(test1
.getCapacity()-1)!=1) {
1046 errln("UnicodeString::releaseBuffer(-1 but no NUL) does not properly set the length of the UnicodeString");
1049 // test getTerminatedBuffer()
1050 test1
=UnicodeString("This is another test.", "");
1051 test2
=UnicodeString("This is another test.", "");
1052 q
=test1
.getTerminatedBuffer();
1053 if(q
[test1
.length()]!=0 || test1
!=test2
|| test2
.compare(q
, -1)!=0) {
1054 errln("getTerminatedBuffer()[length]!=0");
1057 const UChar u
[]={ 5, 6, 7, 8, 0 };
1058 test1
.setTo(FALSE
, u
, 3);
1059 q
=test1
.getTerminatedBuffer();
1060 if(q
==u
|| q
[0]!=5 || q
[1]!=6 || q
[2]!=7 || q
[3]!=0) {
1061 errln("UnicodeString(u[3]).getTerminatedBuffer() returns a bad buffer");
1064 test1
.setTo(TRUE
, u
, -1);
1065 q
=test1
.getTerminatedBuffer();
1066 if(q
!=u
|| test1
.length()!=4 || q
[3]!=8 || q
[4]!=0) {
1067 errln("UnicodeString(u[-1]).getTerminatedBuffer() returns a bad buffer");
1070 test1
=UNICODE_STRING("la", 2);
1071 test1
.append(UNICODE_STRING(" lila", 5).getTerminatedBuffer(), 0, -1);
1072 if(test1
!=UNICODE_STRING("la lila", 7)) {
1073 errln("UnicodeString::append(const UChar *, start, length) failed");
1076 test1
.insert(3, UNICODE_STRING("dudum ", 6), 0, INT32_MAX
);
1077 if(test1
!=UNICODE_STRING("la dudum lila", 13)) {
1078 errln("UnicodeString::insert(start, const UniStr &, start, length) failed");
1081 static const UChar ucs
[]={ 0x68, 0x6d, 0x20, 0 };
1082 test1
.insert(9, ucs
, -1);
1083 if(test1
!=UNICODE_STRING("la dudum hm lila", 16)) {
1084 errln("UnicodeString::insert(start, const UChar *, length) failed");
1087 test1
.replace(9, 2, (UChar
)0x2b);
1088 if(test1
!=UNICODE_STRING("la dudum + lila", 15)) {
1089 errln("UnicodeString::replace(start, length, UChar) failed");
1092 if(test1
.hasMetaData() || UnicodeString().hasMetaData()) {
1093 errln("UnicodeString::hasMetaData() returns TRUE");
1098 UnicodeStringTest::TestStackAllocation()
1100 UChar testString
[] ={
1101 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x63, 0x72, 0x61, 0x7a, 0x79, 0x20, 0x74, 0x65, 0x73, 0x74, 0x2e, 0 };
1102 UChar guardWord
= 0x4DED;
1103 UnicodeString
* test
= 0;
1105 test
= new UnicodeString(testString
);
1106 if (*test
!= "This is a crazy test.")
1107 errln("Test string failed to initialize properly.");
1108 if (guardWord
!= 0x04DED)
1109 errln("Test string initialization overwrote guard word!");
1111 test
->insert(8, "only ");
1112 test
->remove(15, 6);
1113 if (*test
!= "This is only a test.")
1114 errln("Manipulation of test string failed to work right.");
1115 if (guardWord
!= 0x4DED)
1116 errln("Manipulation of test string overwrote guard word!");
1118 // we have to deinitialize and release the backing store by calling the destructor
1119 // explicitly, since we can't overload operator delete
1122 UChar workingBuffer
[] = {
1123 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20,
1124 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6d, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20,
1125 0x63, 0x6f, 0x6d, 0x65, 0xffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1126 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1127 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1128 UChar guardWord2
= 0x4DED;
1130 test
= new UnicodeString(workingBuffer
, 35, 100);
1131 if (*test
!= "Now is the time for all men to come")
1132 errln("Stack-allocated backing store failed to initialize correctly.");
1133 if (guardWord2
!= 0x4DED)
1134 errln("Stack-allocated backing store overwrote guard word!");
1136 test
->insert(24, "good ");
1137 if (*test
!= "Now is the time for all good men to come")
1138 errln("insert() on stack-allocated UnicodeString didn't work right");
1139 if (guardWord2
!= 0x4DED)
1140 errln("insert() on stack-allocated UnicodeString overwrote guard word!");
1142 if (workingBuffer
[24] != 0x67)
1143 errln("insert() on stack-allocated UnicodeString didn't affect backing store");
1145 *test
+= " to the aid of their country.";
1146 if (*test
!= "Now is the time for all good men to come to the aid of their country.")
1147 errln("Stack-allocated UnicodeString overflow didn't work");
1148 if (guardWord2
!= 0x4DED)
1149 errln("Stack-allocated UnicodeString overflow overwrote guard word!");
1153 errln("Assignment to stack-allocated UnicodeString didn't work");
1154 if (workingBuffer
[0] != 0x4e)
1155 errln("Change to UnicodeString after overflow are still affecting original buffer");
1156 if (guardWord2
!= 0x4DED)
1157 errln("Change to UnicodeString after overflow overwrote guard word!");
1159 // test read-only aliasing with setTo()
1160 workingBuffer
[0] = 0x20ac;
1161 workingBuffer
[1] = 0x125;
1162 workingBuffer
[2] = 0;
1163 test
->setTo(TRUE
, workingBuffer
, 2);
1164 if(test
->length() != 2 || test
->charAt(0) != 0x20ac || test
->charAt(1) != 0x125) {
1165 errln("UnicodeString.setTo(readonly alias) does not alias correctly");
1168 UnicodeString
*c
=(UnicodeString
*)test
->clone();
1170 workingBuffer
[1] = 0x109;
1171 if(test
->charAt(1) != 0x109) {
1172 errln("UnicodeString.setTo(readonly alias) made a copy: did not see change in buffer");
1175 if(c
->length() != 2 || c
->charAt(1) != 0x125) {
1176 errln("clone(alias) did not copy the buffer");
1180 test
->setTo(TRUE
, workingBuffer
, -1);
1181 if(test
->length() != 2 || test
->charAt(0) != 0x20ac || test
->charAt(1) != 0x109) {
1182 errln("UnicodeString.setTo(readonly alias, length -1) does not alias correctly");
1185 test
->setTo(FALSE
, workingBuffer
, -1);
1186 if(!test
->isBogus()) {
1187 errln("UnicodeString.setTo(unterminated readonly alias, length -1) does not result in isBogus()");
1192 test
=new UnicodeString();
1193 UChar buffer
[]={0x0061, 0x0062, 0x20ac, 0x0043, 0x0042, 0x0000};
1194 test
->setTo(buffer
, 4, 10);
1195 if(test
->length() !=4 || test
->charAt(0) != 0x0061 || test
->charAt(1) != 0x0062 ||
1196 test
->charAt(2) != 0x20ac || test
->charAt(3) != 0x0043){
1197 errln((UnicodeString
)"UnicodeString.setTo(UChar*, length, capacity) does not work correctly\n" + prettify(*test
));
1202 // test the UChar32 constructor
1203 UnicodeString
c32Test((UChar32
)0x10ff2a);
1204 if( c32Test
.length() != UTF_CHAR_LENGTH(0x10ff2a) ||
1205 c32Test
.char32At(c32Test
.length() - 1) != 0x10ff2a
1207 errln("The UnicodeString(UChar32) constructor does not work with a 0x10ff2a filler");
1210 // test the (new) capacity constructor
1211 UnicodeString
capTest(5, (UChar32
)0x2a, 5);
1212 if( capTest
.length() != 5 * UTF_CHAR_LENGTH(0x2a) ||
1213 capTest
.char32At(0) != 0x2a ||
1214 capTest
.char32At(4) != 0x2a
1216 errln("The UnicodeString capacity constructor does not work with an ASCII filler");
1219 capTest
= UnicodeString(5, (UChar32
)0x10ff2a, 5);
1220 if( capTest
.length() != 5 * UTF_CHAR_LENGTH(0x10ff2a) ||
1221 capTest
.char32At(0) != 0x10ff2a ||
1222 capTest
.char32At(4) != 0x10ff2a
1224 errln("The UnicodeString capacity constructor does not work with a 0x10ff2a filler");
1227 capTest
= UnicodeString(5, (UChar32
)0, 0);
1228 if(capTest
.length() != 0) {
1229 errln("The UnicodeString capacity constructor does not work with a 0x10ff2a filler");
1234 * Test the unescape() function.
1236 void UnicodeStringTest::TestUnescape(void) {
1237 UnicodeString
IN("abc\\u4567 \\n\\r \\U00101234xyz\\x1\\x{5289}\\x1b");
1238 UnicodeString
OUT("abc");
1239 OUT
.append((UChar
)0x4567);
1241 OUT
.append((UChar
)0xA);
1242 OUT
.append((UChar
)0xD);
1244 OUT
.append((UChar32
)0x00101234);
1246 OUT
.append((UChar32
)1).append((UChar32
)0x5289).append((UChar
)0x1b);
1247 UnicodeString result
= IN
.unescape();
1248 if (result
!= OUT
) {
1249 errln("FAIL: " + prettify(IN
) + ".unescape() -> " +
1250 prettify(result
) + ", expected " +
1254 // test that an empty string is returned in case of an error
1255 if (!UNICODE_STRING("wrong \\u sequence", 17).unescape().isEmpty()) {
1256 errln("FAIL: unescaping of a string with an illegal escape sequence did not return an empty string");
1260 /* test code point counting functions --------------------------------------- */
1262 /* reference implementation of UnicodeString::hasMoreChar32Than() */
1264 _refUnicodeStringHasMoreChar32Than(const UnicodeString
&s
, int32_t start
, int32_t length
, int32_t number
) {
1265 int32_t count
=s
.countChar32(start
, length
);
1266 return count
>number
;
1269 /* compare the real function against the reference */
1271 UnicodeStringTest::_testUnicodeStringHasMoreChar32Than(const UnicodeString
&s
, int32_t start
, int32_t length
, int32_t number
) {
1272 if(s
.hasMoreChar32Than(start
, length
, number
)!=_refUnicodeStringHasMoreChar32Than(s
, start
, length
, number
)) {
1273 errln("hasMoreChar32Than(%d, %d, %d)=%hd is wrong\n",
1274 start
, length
, number
, s
.hasMoreChar32Than(start
, length
, number
));
1279 UnicodeStringTest::TestCountChar32(void) {
1281 UnicodeString s
=UNICODE_STRING("\\U0002f999\\U0001d15f\\u00c4\\u1ed0", 32).unescape();
1283 // test countChar32()
1284 // note that this also calls and tests u_countChar32(length>=0)
1286 s
.countChar32()!=4 ||
1287 s
.countChar32(1)!=4 ||
1288 s
.countChar32(2)!=3 ||
1289 s
.countChar32(2, 3)!=2 ||
1290 s
.countChar32(2, 0)!=0
1292 errln("UnicodeString::countChar32() failed");
1295 // NUL-terminate the string buffer and test u_countChar32(length=-1)
1296 const UChar
*buffer
=s
.getTerminatedBuffer();
1298 u_countChar32(buffer
, -1)!=4 ||
1299 u_countChar32(buffer
+1, -1)!=4 ||
1300 u_countChar32(buffer
+2, -1)!=3 ||
1301 u_countChar32(buffer
+3, -1)!=3 ||
1302 u_countChar32(buffer
+4, -1)!=2 ||
1303 u_countChar32(buffer
+5, -1)!=1 ||
1304 u_countChar32(buffer
+6, -1)!=0
1306 errln("u_countChar32(length=-1) failed");
1309 // test u_countChar32() with bad input
1310 if(u_countChar32(NULL
, 5)!=0 || u_countChar32(buffer
, -2)!=0) {
1311 errln("u_countChar32(bad input) failed (returned non-zero counts)");
1315 /* test data and variables for hasMoreChar32Than() */
1316 static const UChar str
[]={
1317 0x61, 0x62, 0xd800, 0xdc00,
1318 0xd801, 0xdc01, 0x63, 0xd802,
1319 0x64, 0xdc03, 0x65, 0x66,
1320 0xd804, 0xdc04, 0xd805, 0xdc05,
1323 UnicodeString
string(str
, LENGTHOF(str
));
1324 int32_t start
, length
, number
;
1326 /* test hasMoreChar32Than() */
1327 for(length
=string
.length(); length
>=0; --length
) {
1328 for(start
=0; start
<=length
; ++start
) {
1329 for(number
=-1; number
<=((length
-start
)+2); ++number
) {
1330 _testUnicodeStringHasMoreChar32Than(string
, start
, length
-start
, number
);
1335 /* test hasMoreChar32Than() with pinning */
1336 for(start
=-1; start
<=string
.length()+1; ++start
) {
1337 for(number
=-1; number
<=((string
.length()-start
)+2); ++number
) {
1338 _testUnicodeStringHasMoreChar32Than(string
, start
, 0x7fffffff, number
);
1342 /* test hasMoreChar32Than() with a bogus string */
1343 string
.setToBogus();
1344 for(length
=-1; length
<=1; ++length
) {
1345 for(start
=-1; start
<=length
; ++start
) {
1346 for(number
=-1; number
<=((length
-start
)+2); ++number
) {
1347 _testUnicodeStringHasMoreChar32Than(string
, start
, length
-start
, number
);
1354 UnicodeStringTest::TestBogus() {
1355 UnicodeString
test1("This is a test");
1356 UnicodeString
test2("This is a test");
1357 UnicodeString
test3("Me too!");
1359 // test isBogus() and setToBogus()
1360 if (test1
.isBogus() || test2
.isBogus() || test3
.isBogus()) {
1361 errln("A string returned TRUE for isBogus()!");
1364 // NULL pointers are treated like empty strings
1365 // use other illegal arguments to make a bogus string
1366 test3
.setTo(FALSE
, test1
.getBuffer(), -2);
1367 if(!test3
.isBogus()) {
1368 errln("A bogus string returned FALSE for isBogus()!");
1370 if (test1
.hashCode() != test2
.hashCode() || test1
.hashCode() == test3
.hashCode()) {
1371 errln("hashCode() failed");
1373 if(test3
.getBuffer()!=0 || test3
.getBuffer(20)!=0 || test3
.getTerminatedBuffer()!=0) {
1374 errln("bogus.getBuffer()!=0");
1377 // verify that non-assignment modifications fail and do not revive a bogus string
1379 test3
.append((UChar
)0x61);
1380 if(!test3
.isBogus() || test3
.getBuffer()!=0) {
1381 errln("bogus.append('a') worked but must not");
1385 test3
.findAndReplace(UnicodeString((UChar
)0x61), test2
);
1386 if(!test3
.isBogus() || test3
.getBuffer()!=0) {
1387 errln("bogus.findAndReplace() worked but must not");
1392 if(!test3
.isBogus() || test3
.getBuffer()!=0) {
1393 errln("bogus.trim() revived bogus but must not");
1398 if(!test3
.isBogus() || test3
.getBuffer()!=0) {
1399 errln("bogus.remove(1) revived bogus but must not");
1403 if(!test3
.setCharAt(0, 0x62).isBogus() || !test3
.isEmpty()) {
1404 errln("bogus.setCharAt(0, 'b') worked but must not");
1408 if(test3
.truncate(1) || !test3
.isBogus() || !test3
.isEmpty()) {
1409 errln("bogus.truncate(1) revived bogus but must not");
1412 // verify that assignments revive a bogus string
1414 if(!test3
.isBogus() || (test3
=test1
).isBogus() || test3
!=test1
) {
1415 errln("bogus.operator=() failed");
1419 if(!test3
.isBogus() || test3
.fastCopyFrom(test1
).isBogus() || test3
!=test1
) {
1420 errln("bogus.fastCopyFrom() failed");
1424 if(!test3
.isBogus() || test3
.setTo(test1
).isBogus() || test3
!=test1
) {
1425 errln("bogus.setTo(UniStr) failed");
1429 if(!test3
.isBogus() || test3
.setTo(test1
, 0).isBogus() || test3
!=test1
) {
1430 errln("bogus.setTo(UniStr, 0) failed");
1434 if(!test3
.isBogus() || test3
.setTo(test1
, 0, 0x7fffffff).isBogus() || test3
!=test1
) {
1435 errln("bogus.setTo(UniStr, 0, len) failed");
1439 if(!test3
.isBogus() || test3
.setTo(test1
.getBuffer(), test1
.length()).isBogus() || test3
!=test1
) {
1440 errln("bogus.setTo(const UChar *, len) failed");
1444 if(!test3
.isBogus() || test3
.setTo((UChar
)0x2028).isBogus() || test3
!=UnicodeString((UChar
)0x2028)) {
1445 errln("bogus.setTo(UChar) failed");
1449 if(!test3
.isBogus() || test3
.setTo((UChar32
)0x1d157).isBogus() || test3
!=UnicodeString((UChar32
)0x1d157)) {
1450 errln("bogus.setTo(UChar32) failed");
1454 if(!test3
.isBogus() || test3
.setTo(FALSE
, test1
.getBuffer(), test1
.length()).isBogus() || test3
!=test1
) {
1455 errln("bogus.setTo(readonly alias) failed");
1458 // writable alias to another string's buffer: very bad idea, just convenient for this test
1460 if(!test3
.isBogus() || test3
.setTo((UChar
*)test1
.getBuffer(), test1
.length(), test1
.getCapacity()).isBogus() || test3
!=test1
) {
1461 errln("bogus.setTo(writable alias) failed");
1464 // verify simple, documented ways to turn a bogus string into an empty one
1466 if(!test3
.isBogus() || (test3
=UnicodeString()).isBogus() || !test3
.isEmpty()) {
1467 errln("bogus.operator=(UnicodeString()) failed");
1471 if(!test3
.isBogus() || test3
.setTo(UnicodeString()).isBogus() || !test3
.isEmpty()) {
1472 errln("bogus.setTo(UnicodeString()) failed");
1476 if(test3
.remove().isBogus() || test3
.getBuffer()==0 || !test3
.isEmpty()) {
1477 errln("bogus.remove() failed");
1481 if(test3
.remove(0, INT32_MAX
).isBogus() || test3
.getBuffer()==0 || !test3
.isEmpty()) {
1482 errln("bogus.remove(0, INT32_MAX) failed");
1486 if(test3
.truncate(0) || test3
.isBogus() || !test3
.isEmpty()) {
1487 errln("bogus.truncate(0) failed");
1491 if(!test3
.isBogus() || test3
.setTo((UChar32
)-1).isBogus() || !test3
.isEmpty()) {
1492 errln("bogus.setTo((UChar32)-1) failed");
1495 static const UChar nul
=0;
1498 if(!test3
.isBogus() || test3
.setTo(&nul
, 0).isBogus() || !test3
.isEmpty()) {
1499 errln("bogus.setTo(&nul, 0) failed");
1503 if(!test3
.isBogus() || test3
.getBuffer()!=0) {
1504 errln("setToBogus() failed to make a string bogus");
1508 if(test1
.isBogus() || !(test1
=test3
).isBogus()) {
1509 errln("normal=bogus failed to make the left string bogus");
1512 // test that NULL primitive input string values are treated like
1513 // empty strings, not errors (bogus)
1514 test2
.setTo((UChar32
)0x10005);
1515 if(test2
.insert(1, NULL
, 1).length()!=2) {
1516 errln("UniStr.insert(...NULL...) should not modify the string but does");
1519 UErrorCode errorCode
=U_ZERO_ERROR
;
1521 test4((const UChar
*)NULL
),
1522 test5(TRUE
, (const UChar
*)NULL
, 1),
1523 test6((UChar
*)NULL
, 5, 5),
1524 test7((const char *)NULL
, 3, NULL
, errorCode
);
1525 if(test4
.isBogus() || test5
.isBogus() || test6
.isBogus() || test7
.isBogus()) {
1526 errln("a constructor set to bogus for a NULL input string, should be empty");
1529 test4
.setTo(NULL
, 3);
1530 test5
.setTo(TRUE
, (const UChar
*)NULL
, 1);
1531 test6
.setTo((UChar
*)NULL
, 5, 5);
1532 if(test4
.isBogus() || test5
.isBogus() || test6
.isBogus()) {
1533 errln("a setTo() set to bogus for a NULL input string, should be empty");
1536 // test that bogus==bogus<any
1537 if(test1
!=test3
|| test1
.compare(test3
)!=0) {
1538 errln("bogus==bogus failed");
1542 if(test1
>=test2
|| !(test2
>test1
) || test1
.compare(test2
)>=0 || !(test2
.compare(test1
)>0)) {
1543 errln("bogus<empty failed");
1547 // StringEnumeration ------------------------------------------------------- ***
1548 // most of StringEnumeration is tested elsewhere
1549 // this test improves code coverage
1551 static const char *const
1556 "this is a long string which helps us test some buffer limits",
1557 "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
1560 class TestEnumeration
: public StringEnumeration
{
1562 TestEnumeration() : i(0) {}
1564 virtual int32_t count(UErrorCode
& /*status*/) const {
1565 return LENGTHOF(testEnumStrings
);
1568 virtual const UnicodeString
*snext(UErrorCode
&status
) {
1569 if(U_SUCCESS(status
) && i
<LENGTHOF(testEnumStrings
)) {
1570 unistr
=UnicodeString(testEnumStrings
[i
++], "");
1577 virtual void reset(UErrorCode
& /*status*/) {
1581 static inline UClassID
getStaticClassID() {
1582 return (UClassID
)&fgClassID
;
1584 virtual UClassID
getDynamicClassID() const {
1585 return getStaticClassID();
1589 static const char fgClassID
;
1594 const char TestEnumeration::fgClassID
=0;
1597 UnicodeStringTest::TestStringEnumeration() {
1599 TestEnumeration ten
;
1606 // test the next() default implementation and ensureCharsCapacity()
1607 for(i
=0; i
<LENGTHOF(testEnumStrings
); ++i
) {
1608 status
=U_ZERO_ERROR
;
1609 pc
=ten
.next(&length
, status
);
1610 s
=UnicodeString(testEnumStrings
[i
], "");
1611 if(U_FAILURE(status
) || pc
==NULL
|| length
!=s
.length() || UnicodeString(pc
, length
, "")!=s
) {
1612 errln("StringEnumeration.next(%d) failed", i
);
1615 status
=U_ZERO_ERROR
;
1616 if(ten
.next(&length
, status
)!=NULL
) {
1617 errln("StringEnumeration.next(done)!=NULL");
1620 // test the unext() default implementation
1622 for(i
=0; i
<LENGTHOF(testEnumStrings
); ++i
) {
1623 status
=U_ZERO_ERROR
;
1624 pu
=ten
.unext(&length
, status
);
1625 s
=UnicodeString(testEnumStrings
[i
], "");
1626 if(U_FAILURE(status
) || pu
==NULL
|| length
!=s
.length() || UnicodeString(TRUE
, pu
, length
)!=s
) {
1627 errln("StringEnumeration.unext(%d) failed", i
);
1630 status
=U_ZERO_ERROR
;
1631 if(ten
.unext(&length
, status
)!=NULL
) {
1632 errln("StringEnumeration.unext(done)!=NULL");
1635 // test that the default clone() implementation works, and returns NULL
1636 if(ten
.clone()!=NULL
) {
1637 errln("StringEnumeration.clone()!=NULL");
1642 UnicodeStringTest::TestCharString() {
1643 static const char originalCStr
[] =
1644 "This is a large string that is meant to over flow the internal buffer of CharString. At the time of writing this test, the internal buffer is 128 bytes.";
1645 CharString
chStr(originalCStr
);
1646 if (strcmp(originalCStr
, chStr
) != 0) {
1647 errln("CharString doesn't work with large strings.");