1 /********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1997-2007, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
6
7 #include "ustrtest.h"
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"
13 #include "cmemory.h"
14 #include "charstr.h"
15
16 #if 0
17 #include "unicode/ustream.h"
18
19 #if U_IOSTREAM_SOURCE >= 199711
20 #include <iostream>
21 using namespace std;
22 #elif U_IOSTREAM_SOURCE >= 198506
23 #include <iostream.h>
24 #endif
25
26 #endif
27
28 #define LENGTHOF(array) (int32_t)((sizeof(array)/sizeof((array)[0])))
29
~UnicodeStringTest()30 UnicodeStringTest::~UnicodeStringTest() {}
31
runIndexedTest(int32_t index,UBool exec,const char * & name,char * par)32 void UnicodeStringTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char *par)
33 {
34 if (exec) logln("TestSuite UnicodeStringTest: ");
35 switch (index) {
36 case 0:
37 name = "StringCaseTest";
38 if (exec) {
39 logln("StringCaseTest---"); logln("");
40 StringCaseTest test;
41 callTest(test, par);
42 }
43 break;
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;
60 case 17: name = "TestNameSpace"; if (exec) TestNameSpace(); break;
61
62 default: name = ""; break; //needed to end loop
63 }
64 }
65
66 void
TestBasicManipulation()67 UnicodeStringTest::TestBasicManipulation()
68 {
69 UnicodeString test1("Now is the time for all men to come swiftly to the aid of the party.\n");
70 UnicodeString expectedValue;
71 UnicodeString *c;
72
73 c=(UnicodeString *)test1.clone();
74 test1.insert(24, "good ");
75 expectedValue = "Now is the time for all good men to come swiftly to the aid of the party.\n";
76 if (test1 != expectedValue)
77 errln("insert() failed: expected \"" + expectedValue + "\"\n,got \"" + test1 + "\"");
78
79 c->insert(24, "good ");
80 if(*c != expectedValue) {
81 errln("clone()->insert() failed: expected \"" + expectedValue + "\"\n,got \"" + *c + "\"");
82 }
83 delete c;
84
85 test1.remove(41, 8);
86 expectedValue = "Now is the time for all good men to come to the aid of the party.\n";
87 if (test1 != expectedValue)
88 errln("remove() failed: expected \"" + expectedValue + "\"\n,got \"" + test1 + "\"");
89
90 test1.replace(58, 6, "ir country");
91 expectedValue = "Now is the time for all good men to come to the aid of their country.\n";
92 if (test1 != expectedValue)
93 errln("replace() failed: expected \"" + expectedValue + "\"\n,got \"" + test1 + "\"");
94
95 UChar temp[80];
96 test1.extract(0, 15, temp);
97
98 UnicodeString test2(temp, 15);
99
100 expectedValue = "Now is the time";
101 if (test2 != expectedValue)
102 errln("extract() failed: expected \"" + expectedValue + "\"\n,got \"" + test2 + "\"");
103
104 test2 += " for me to go!\n";
105 expectedValue = "Now is the time for me to go!\n";
106 if (test2 != expectedValue)
107 errln("operator+=() failed: expected \"" + expectedValue + "\"\n,got \"" + test2 + "\"");
108
109 if (test1.length() != 70)
110 errln("length() failed: expected 70, got " + test1.length());
111 if (test2.length() != 30)
112 errln("length() failed: expected 30, got " + test2.length());
113
114 UnicodeString test3;
115 test3.append((UChar32)0x20402);
116 if(test3 != CharsToUnicodeString("\\uD841\\uDC02")){
117 errln((UnicodeString)"append failed for UChar32, expected \"\\\\ud841\\\\udc02\", got " + prettify(test3));
118 }
119 if(test3.length() != 2){
120 errln("append or length failed for UChar32, expected 2, got " + test3.length());
121 }
122 test3.append((UChar32)0x0074);
123 if(test3 != CharsToUnicodeString("\\uD841\\uDC02t")){
124 errln((UnicodeString)"append failed for UChar32, expected \"\\\\uD841\\\\uDC02t\", got " + prettify(test3));
125 }
126 if(test3.length() != 3){
127 errln((UnicodeString)"append or length failed for UChar32, expected 2, got " + test3.length());
128 }
129
130 // test some UChar32 overloads
131 if( test3.setTo((UChar32)0x10330).length() != 2 ||
132 test3.insert(0, (UChar32)0x20100).length() != 4 ||
133 test3.replace(2, 2, (UChar32)0xe0061).length() != 4 ||
134 (test3 = (UChar32)0x14001).length() != 2
135 ) {
136 errln((UnicodeString)"simple UChar32 overloads for replace, insert, setTo or = failed");
137 }
138
139 {
140 // test moveIndex32()
141 UnicodeString s=UNICODE_STRING("\\U0002f999\\U0001d15f\\u00c4\\u1ed0", 32).unescape();
142
143 if(
144 s.moveIndex32(2, -1)!=0 ||
145 s.moveIndex32(2, 1)!=4 ||
146 s.moveIndex32(2, 2)!=5 ||
147 s.moveIndex32(5, -2)!=2 ||
148 s.moveIndex32(0, -1)!=0 ||
149 s.moveIndex32(6, 1)!=6
150 ) {
151 errln("UnicodeString::moveIndex32() failed");
152 }
153
154 if(s.getChar32Start(1)!=0 || s.getChar32Start(2)!=2) {
155 errln("UnicodeString::getChar32Start() failed");
156 }
157
158 if(s.getChar32Limit(1)!=2 || s.getChar32Limit(2)!=2) {
159 errln("UnicodeString::getChar32Limit() failed");
160 }
161 }
162
163 {
164 // test new 2.2 constructors and setTo function that parallel Java's substring function.
165 UnicodeString src("Hello folks how are you?");
166 UnicodeString target1("how are you?");
167 if (target1 != UnicodeString(src, 12)) {
168 errln("UnicodeString(const UnicodeString&, int32_t) failed");
169 }
170 UnicodeString target2("folks");
171 if (target2 != UnicodeString(src, 6, 5)) {
172 errln("UnicodeString(const UnicodeString&, int32_t, int32_t) failed");
173 }
174 if (target1 != target2.setTo(src, 12)) {
175 errln("UnicodeString::setTo(const UnicodeString&, int32_t) failed");
176 }
177 }
178
179 {
180 // op+ is new in ICU 2.8
181 UnicodeString s=UnicodeString("abc", "")+UnicodeString("def", "")+UnicodeString("ghi", "");
182 if(s!=UnicodeString("abcdefghi", "")) {
183 errln("operator+(UniStr, UniStr) failed");
184 }
185 }
186
187 {
188 // tests for Jitterbug 2360
189 // verify that APIs with source pointer + length accept length == -1
190 // mostly test only where modified, only few functions did not already do this
191 if(UnicodeString("abc", -1, "")!=UnicodeString("abc", "")) {
192 errln("UnicodeString(codepageData, dataLength, codepage) does not work with dataLength==-1");
193 }
194
195 UChar buffer[10]={ 0x61, 0x62, 0x20ac, 0xd900, 0xdc05, 0, 0x62, 0xffff, 0xdbff, 0xdfff };
196 UnicodeString s, t(buffer, -1, LENGTHOF(buffer));
197
198 if(s.setTo(buffer, -1, LENGTHOF(buffer)).length()!=u_strlen(buffer)) {
199 errln("UnicodeString.setTo(buffer, length, capacity) does not work with length==-1");
200 }
201 if(t.length()!=u_strlen(buffer)) {
202 errln("UnicodeString(buffer, length, capacity) does not work with length==-1");
203 }
204
205 if(0!=s.caseCompare(buffer, -1, U_FOLD_CASE_DEFAULT)) {
206 errln("UnicodeString.caseCompare(const UChar *, length, options) does not work with length==-1");
207 }
208 if(0!=s.caseCompare(0, s.length(), buffer, U_FOLD_CASE_DEFAULT)) {
209 errln("UnicodeString.caseCompare(start, _length, const UChar *, options) does not work");
210 }
211
212 buffer[u_strlen(buffer)]=0xe4;
213 UnicodeString u(buffer, -1, LENGTHOF(buffer));
214 if(s.setTo(buffer, -1, LENGTHOF(buffer)).length()!=LENGTHOF(buffer)) {
215 errln("UnicodeString.setTo(buffer without NUL, length, capacity) does not work with length==-1");
216 }
217 if(u.length()!=LENGTHOF(buffer)) {
218 errln("UnicodeString(buffer without NUL, length, capacity) does not work with length==-1");
219 }
220
221 static const char cs[]={ 0x61, (char)0xe4, (char)0x85, 0 };
222 UConverter *cnv;
223 UErrorCode errorCode=U_ZERO_ERROR;
224
225 cnv=ucnv_open("ISO-8859-1", &errorCode);
226 UnicodeString v(cs, -1, cnv, errorCode);
227 ucnv_close(cnv);
228 if(v!=UnicodeString("a\\xe4\\x85").unescape()) {
229 errln("UnicodeString(const char *, length, cnv, errorCode) does not work with length==-1");
230 }
231 }
232 }
233
234 void
TestCompare()235 UnicodeStringTest::TestCompare()
236 {
237 UnicodeString test1("this is a test");
238 UnicodeString test2("this is a test");
239 UnicodeString test3("this is a test of the emergency broadcast system");
240 UnicodeString test4("never say, \"this is a test\"!!");
241
242 UnicodeString test5((UChar)0x5000);
243 UnicodeString test6((UChar)0x5100);
244
245 UChar uniChars[] = { 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73,
246 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0 };
247 char chars[] = "this is a test";
248
249 // test operator== and operator!=
250 if (test1 != test2 || test1 == test3 || test1 == test4)
251 errln("operator== or operator!= failed");
252
253 // test operator> and operator<
254 if (test1 > test2 || test1 < test2 || !(test1 < test3) || !(test1 > test4) ||
255 !(test5 < test6)
256 ) {
257 errln("operator> or operator< failed");
258 }
259
260 // test operator>= and operator<=
261 if (!(test1 >= test2) || !(test1 <= test2) || !(test1 <= test3) || !(test1 >= test4))
262 errln("operator>= or operator<= failed");
263
264 // test compare(UnicodeString)
265 if (test1.compare(test2) != 0 || test1.compare(test3) >= 0 || test1.compare(test4) <= 0)
266 errln("compare(UnicodeString) failed");
267
268 //test compare(offset, length, UnicodeString)
269 if(test1.compare(0, 14, test2) != 0 ||
270 test3.compare(0, 14, test2) != 0 ||
271 test4.compare(12, 14, test2) != 0 ||
272 test3.compare(0, 18, test1) <=0 )
273 errln("compare(offset, length, UnicodeString) failes");
274
275 // test compare(UChar*)
276 if (test2.compare(uniChars) != 0 || test3.compare(uniChars) <= 0 || test4.compare(uniChars) >= 0)
277 errln("compare(UChar*) failed");
278
279 // test compare(char*)
280 if (test2.compare(chars) != 0 || test3.compare(chars) <= 0 || test4.compare(chars) >= 0)
281 errln("compare(char*) failed");
282
283 // test compare(UChar*, length)
284 if (test1.compare(uniChars, 4) <= 0 || test1.compare(uniChars, 4) <= 0)
285 errln("compare(UChar*, length) failed");
286
287 // test compare(thisOffset, thisLength, that, thatOffset, thatLength)
288 if (test1.compare(0, 14, test2, 0, 14) != 0
289 || test1.compare(0, 14, test3, 0, 14) != 0
290 || test1.compare(0, 14, test4, 12, 14) != 0)
291 errln("1. compare(thisOffset, thisLength, that, thatOffset, thatLength) failed");
292
293 if (test1.compare(10, 4, test2, 0, 4) >= 0
294 || test1.compare(10, 4, test3, 22, 9) <= 0
295 || test1.compare(10, 4, test4, 22, 4) != 0)
296 errln("2. compare(thisOffset, thisLength, that, thatOffset, thatLength) failed");
297
298 // test compareBetween
299 if (test1.compareBetween(0, 14, test2, 0, 14) != 0 || test1.compareBetween(0, 14, test3, 0, 14) != 0
300 || test1.compareBetween(0, 14, test4, 12, 26) != 0)
301 errln("compareBetween failed");
302
303 if (test1.compareBetween(10, 14, test2, 0, 4) >= 0 || test1.compareBetween(10, 14, test3, 22, 31) <= 0
304 || test1.compareBetween(10, 14, test4, 22, 26) != 0)
305 errln("compareBetween failed");
306
307 // test compare() etc. with strings that share a buffer but are not equal
308 test2=test1; // share the buffer, length() too large for the stackBuffer
309 test2.truncate(1); // change only the length, not the buffer
310 if( test1==test2 || test1<=test2 ||
311 test1.compare(test2)<=0 ||
312 test1.compareCodePointOrder(test2)<=0 ||
313 test1.compareCodePointOrder(0, INT32_MAX, test2)<=0 ||
314 test1.compareCodePointOrder(0, INT32_MAX, test2, 0, INT32_MAX)<=0 ||
315 test1.compareCodePointOrderBetween(0, INT32_MAX, test2, 0, INT32_MAX)<=0 ||
316 test1.caseCompare(test2, U_FOLD_CASE_DEFAULT)<=0
317 ) {
318 errln("UnicodeStrings that share a buffer but have different lengths compare as equal");
319 }
320
321 /* test compareCodePointOrder() */
322 {
323 /* these strings are in ascending order */
324 static const UChar strings[][4]={
325 { 0x61, 0 }, /* U+0061 */
326 { 0x20ac, 0xd801, 0 }, /* U+20ac U+d801 */
327 { 0x20ac, 0xd800, 0xdc00, 0 }, /* U+20ac U+10000 */
328 { 0xd800, 0 }, /* U+d800 */
329 { 0xd800, 0xff61, 0 }, /* U+d800 U+ff61 */
330 { 0xdfff, 0 }, /* U+dfff */
331 { 0xff61, 0xdfff, 0 }, /* U+ff61 U+dfff */
332 { 0xff61, 0xd800, 0xdc02, 0 }, /* U+ff61 U+10002 */
333 { 0xd800, 0xdc02, 0 }, /* U+10002 */
334 { 0xd84d, 0xdc56, 0 } /* U+23456 */
335 };
336 UnicodeString u[20]; // must be at least as long as strings[]
337 int32_t i;
338
339 for(i=0; i<(int32_t)(sizeof(strings)/sizeof(strings[0])); ++i) {
340 u[i]=UnicodeString(TRUE, strings[i], -1);
341 }
342
343 for(i=0; i<(int32_t)(sizeof(strings)/sizeof(strings[0])-1); ++i) {
344 if(u[i].compareCodePointOrder(u[i+1])>=0 || u[i].compareCodePointOrder(0, INT32_MAX, u[i+1].getBuffer())>=0) {
345 errln("error: UnicodeString::compareCodePointOrder() fails for string %d and the following one\n", i);
346 }
347 }
348 }
349
350 /* test caseCompare() */
351 {
352 static const UChar
353 _mixed[]= { 0x61, 0x42, 0x131, 0x3a3, 0xdf, 0x130, 0x49, 0xfb03, 0xd93f, 0xdfff, 0 },
354 _otherDefault[]= { 0x41, 0x62, 0x131, 0x3c3, 0x73, 0x53, 0x69, 0x307, 0x69, 0x46, 0x66, 0x49, 0xd93f, 0xdfff, 0 },
355 _otherExcludeSpecialI[]={ 0x41, 0x62, 0x131, 0x3c3, 0x53, 0x73, 0x69, 0x131, 0x66, 0x46, 0x69, 0xd93f, 0xdfff, 0 },
356 _different[]= { 0x41, 0x62, 0x131, 0x3c3, 0x73, 0x53, 0x130, 0x49, 0x46, 0x66, 0x49, 0xd93f, 0xdffd, 0 };
357
358 UnicodeString
359 mixed(TRUE, _mixed, -1),
360 otherDefault(TRUE, _otherDefault, -1),
361 otherExcludeSpecialI(TRUE, _otherExcludeSpecialI, -1),
362 different(TRUE, _different, -1);
363
364 int8_t result;
365
366 /* test caseCompare() */
367 result=mixed.caseCompare(otherDefault, U_FOLD_CASE_DEFAULT);
368 if(result!=0 || 0!=mixed.caseCompareBetween(0, INT32_MAX, otherDefault, 0, INT32_MAX, U_FOLD_CASE_DEFAULT)) {
369 errln("error: mixed.caseCompare(other, default)=%ld instead of 0\n", result);
370 }
371 result=mixed.caseCompare(otherExcludeSpecialI, U_FOLD_CASE_EXCLUDE_SPECIAL_I);
372 if(result!=0) {
373 errln("error: mixed.caseCompare(otherExcludeSpecialI, U_FOLD_CASE_EXCLUDE_SPECIAL_I)=%ld instead of 0\n", result);
374 }
375 result=mixed.caseCompare(otherDefault, U_FOLD_CASE_EXCLUDE_SPECIAL_I);
376 if(result==0 || 0==mixed.caseCompareBetween(0, INT32_MAX, otherDefault, 0, INT32_MAX, U_FOLD_CASE_EXCLUDE_SPECIAL_I)) {
377 errln("error: mixed.caseCompare(other, U_FOLD_CASE_EXCLUDE_SPECIAL_I)=0 instead of !=0\n");
378 }
379
380 /* test caseCompare() */
381 result=mixed.caseCompare(different, U_FOLD_CASE_DEFAULT);
382 if(result<=0) {
383 errln("error: mixed.caseCompare(different, default)=%ld instead of positive\n", result);
384 }
385
386 /* test caseCompare() - include the folded sharp s (U+00df) with different lengths */
387 result=mixed.caseCompare(1, 4, different, 1, 5, U_FOLD_CASE_DEFAULT);
388 if(result!=0 || 0!=mixed.caseCompareBetween(1, 5, different, 1, 6, U_FOLD_CASE_DEFAULT)) {
389 errln("error: mixed.caseCompare(mixed, 1, 4, different, 1, 5, default)=%ld instead of 0\n", result);
390 }
391
392 /* test caseCompare() - stop in the middle of the sharp s (U+00df) */
393 result=mixed.caseCompare(1, 4, different, 1, 4, U_FOLD_CASE_DEFAULT);
394 if(result<=0) {
395 errln("error: mixed.caseCompare(1, 4, different, 1, 4, default)=%ld instead of positive\n", result);
396 }
397 }
398
399 // test that srcLength=-1 is handled in functions that
400 // take input const UChar */int32_t srcLength (j785)
401 {
402 static const UChar u[]={ 0x61, 0x308, 0x62, 0 };
403 UnicodeString s=UNICODE_STRING("a\\u0308b", 8).unescape();
404
405 if(s.compare(u, -1)!=0 || s.compare(0, 999, u, 0, -1)!=0) {
406 errln("error UnicodeString::compare(..., const UChar *, srcLength=-1) does not work");
407 }
408
409 if(s.compareCodePointOrder(u, -1)!=0 || s.compareCodePointOrder(0, 999, u, 0, -1)!=0) {
410 errln("error UnicodeString::compareCodePointOrder(..., const UChar *, srcLength=-1, ...) does not work");
411 }
412
413 if(s.caseCompare(u, -1, U_FOLD_CASE_DEFAULT)!=0 || s.caseCompare(0, 999, u, 0, -1, U_FOLD_CASE_DEFAULT)!=0) {
414 errln("error UnicodeString::caseCompare(..., const UChar *, srcLength=-1, ...) does not work");
415 }
416
417 if(s.indexOf(u, 1, -1, 0, 999)!=1 || s.indexOf(u+1, -1, 0, 999)!=1 || s.indexOf(u+1, -1, 0)!=1) {
418 errln("error UnicodeString::indexOf(const UChar *, srcLength=-1, ...) does not work");
419 }
420
421 if(s.lastIndexOf(u, 1, -1, 0, 999)!=1 || s.lastIndexOf(u+1, -1, 0, 999)!=1 || s.lastIndexOf(u+1, -1, 0)!=1) {
422 errln("error UnicodeString::lastIndexOf(const UChar *, srcLength=-1, ...) does not work");
423 }
424
425 UnicodeString s2, s3;
426 s2.replace(0, 0, u+1, -1);
427 s3.replace(0, 0, u, 1, -1);
428 if(s.compare(1, 999, s2)!=0 || s2!=s3) {
429 errln("error UnicodeString::replace(..., const UChar *, srcLength=-1, ...) does not work");
430 }
431 }
432 }
433
434 void
TestExtract()435 UnicodeStringTest::TestExtract()
436 {
437 UnicodeString test1("Now is the time for all good men to come to the aid of their country.", "");
438 UnicodeString test2;
439 UChar test3[13] = {1, 2, 3, 4, 5, 6, 7, 8, 8, 10, 11, 12, 13};
440 char test4[13] = {1, 2, 3, 4, 5, 6, 7, 8, 8, 10, 11, 12, 13};
441 UnicodeString test5;
442 char test6[13] = {1, 2, 3, 4, 5, 6, 7, 8, 8, 10, 11, 12, 13};
443
444 test1.extract(11, 12, test2);
445 test1.extract(11, 12, test3);
446 if (test1.extract(11, 12, test4) != 12 || test4[12] != 0) {
447 errln("UnicodeString.extract(char *) failed to return the correct size of destination buffer.");
448 }
449
450 // test proper pinning in extractBetween()
451 test1.extractBetween(-3, 7, test5);
452 if(test5!=UNICODE_STRING("Now is ", 7)) {
453 errln("UnicodeString.extractBetween(-3, 7) did not pin properly.");
454 }
455
456 test1.extractBetween(11, 23, test5);
457 if (test1.extract(60, 71, test6) != 9) {
458 errln("UnicodeString.extract() failed to return the correct size of destination buffer for end of buffer.");
459 }
460 if (test1.extract(11, 12, test6) != 12) {
461 errln("UnicodeString.extract() failed to return the correct size of destination buffer.");
462 }
463
464 // convert test4 back to Unicode for comparison
465 UnicodeString test4b(test4, 12);
466
467 if (test1.extract(11, 12, (char *)NULL) != 12) {
468 errln("UnicodeString.extract(NULL) failed to return the correct size of destination buffer.");
469 }
470 if (test1.extract(11, -1, test6) != 0) {
471 errln("UnicodeString.extract(-1) failed to stop reading the string.");
472 }
473
474 for (int32_t i = 0; i < 12; i++) {
475 if (test1.charAt((int32_t)(11 + i)) != test2.charAt(i)) {
476 errln(UnicodeString("extracting into a UnicodeString failed at position ") + i);
477 break;
478 }
479 if (test1.charAt((int32_t)(11 + i)) != test3[i]) {
480 errln(UnicodeString("extracting into an array of UChar failed at position ") + i);
481 break;
482 }
483 if (((char)test1.charAt((int32_t)(11 + i))) != test4b.charAt(i)) {
484 errln(UnicodeString("extracting into an array of char failed at position ") + i);
485 break;
486 }
487 if (test1.charAt((int32_t)(11 + i)) != test5.charAt(i)) {
488 errln(UnicodeString("extracting with extractBetween failed at position ") + i);
489 break;
490 }
491 }
492
493 // test preflighting and overflows with invariant conversion
494 if (test1.extract(0, 10, (char *)NULL, "") != 10) {
495 errln("UnicodeString.extract(0, 10, (char *)NULL, \"\") != 10");
496 }
497
498 test4[2] = (char)0xff;
499 if (test1.extract(0, 10, test4, 2, "") != 10) {
500 errln("UnicodeString.extract(0, 10, test4, 2, \"\") != 10");
501 }
502 if (test4[2] != (char)0xff) {
503 errln("UnicodeString.extract(0, 10, test4, 2, \"\") overwrote test4[2]");
504 }
505
506 {
507 // test new, NUL-terminating extract() function
508 UnicodeString s("terminate", "");
509 UChar dest[20]={
510 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
511 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5
512 };
513 UErrorCode errorCode;
514 int32_t length;
515
516 errorCode=U_ZERO_ERROR;
517 length=s.extract((UChar *)NULL, 0, errorCode);
518 if(errorCode!=U_BUFFER_OVERFLOW_ERROR || length!=s.length()) {
519 errln("UnicodeString.extract(NULL, 0)==%d (%s) expected %d (U_BUFFER_OVERFLOW_ERROR)", length, s.length(), u_errorName(errorCode));
520 }
521
522 errorCode=U_ZERO_ERROR;
523 length=s.extract(dest, s.length()-1, errorCode);
524 if(errorCode!=U_BUFFER_OVERFLOW_ERROR || length!=s.length()) {
525 errln("UnicodeString.extract(dest too short)==%d (%s) expected %d (U_BUFFER_OVERFLOW_ERROR)",
526 length, u_errorName(errorCode), s.length());
527 }
528
529 errorCode=U_ZERO_ERROR;
530 length=s.extract(dest, s.length(), errorCode);
531 if(errorCode!=U_STRING_NOT_TERMINATED_WARNING || length!=s.length()) {
532 errln("UnicodeString.extract(dest just right without NUL)==%d (%s) expected %d (U_STRING_NOT_TERMINATED_WARNING)",
533 length, u_errorName(errorCode), s.length());
534 }
535 if(dest[length-1]!=s[length-1] || dest[length]!=0xa5) {
536 errln("UnicodeString.extract(dest just right without NUL) did not extract the string correctly");
537 }
538
539 errorCode=U_ZERO_ERROR;
540 length=s.extract(dest, s.length()+1, errorCode);
541 if(errorCode!=U_ZERO_ERROR || length!=s.length()) {
542 errln("UnicodeString.extract(dest large enough)==%d (%s) expected %d (U_ZERO_ERROR)",
543 length, u_errorName(errorCode), s.length());
544 }
545 if(dest[length-1]!=s[length-1] || dest[length]!=0 || dest[length+1]!=0xa5) {
546 errln("UnicodeString.extract(dest large enough) did not extract the string correctly");
547 }
548 }
549
550 {
551 // test new UConverter extract() and constructor
552 UnicodeString s=UNICODE_STRING("\\U0002f999\\U0001d15f\\u00c4\\u1ed0", 32).unescape();
553 char buffer[32];
554 static const char expect[]={
555 (char)0xf0, (char)0xaf, (char)0xa6, (char)0x99,
556 (char)0xf0, (char)0x9d, (char)0x85, (char)0x9f,
557 (char)0xc3, (char)0x84,
558 (char)0xe1, (char)0xbb, (char)0x90
559 };
560 UErrorCode errorCode=U_ZERO_ERROR;
561 UConverter *cnv=ucnv_open("UTF-8", &errorCode);
562 int32_t length;
563
564 if(U_SUCCESS(errorCode)) {
565 // test preflighting
566 if( (length=s.extract(NULL, 0, cnv, errorCode))!=13 ||
567 errorCode!=U_BUFFER_OVERFLOW_ERROR
568 ) {
569 errln("UnicodeString::extract(NULL, UConverter) preflighting failed (length=%ld, %s)",
570 length, u_errorName(errorCode));
571 }
572 errorCode=U_ZERO_ERROR;
573 if( (length=s.extract(buffer, 2, cnv, errorCode))!=13 ||
574 errorCode!=U_BUFFER_OVERFLOW_ERROR
575 ) {
576 errln("UnicodeString::extract(too small, UConverter) preflighting failed (length=%ld, %s)",
577 length, u_errorName(errorCode));
578 }
579
580 // try error cases
581 errorCode=U_ZERO_ERROR;
582 if( s.extract(NULL, 2, cnv, errorCode)==13 || U_SUCCESS(errorCode)) {
583 errln("UnicodeString::extract(UConverter) succeeded with an illegal destination");
584 }
585 errorCode=U_ILLEGAL_ARGUMENT_ERROR;
586 if( s.extract(NULL, 0, cnv, errorCode)==13 || U_SUCCESS(errorCode)) {
587 errln("UnicodeString::extract(UConverter) succeeded with a previous error code");
588 }
589 errorCode=U_ZERO_ERROR;
590
591 // extract for real
592 if( (length=s.extract(buffer, sizeof(buffer), cnv, errorCode))!=13 ||
593 uprv_memcmp(buffer, expect, 13)!=0 ||
594 buffer[13]!=0 ||
595 U_FAILURE(errorCode)
596 ) {
597 errln("UnicodeString::extract(UConverter) conversion failed (length=%ld, %s)",
598 length, u_errorName(errorCode));
599 }
600 // Test again with just the converter name.
601 if( (length=s.extract(0, s.length(), buffer, sizeof(buffer), "UTF-8"))!=13 ||
602 uprv_memcmp(buffer, expect, 13)!=0 ||
603 buffer[13]!=0 ||
604 U_FAILURE(errorCode)
605 ) {
606 errln("UnicodeString::extract(\"UTF-8\") conversion failed (length=%ld, %s)",
607 length, u_errorName(errorCode));
608 }
609
610 // try the constructor
611 UnicodeString t(expect, sizeof(expect), cnv, errorCode);
612 if(U_FAILURE(errorCode) || s!=t) {
613 errln("UnicodeString(UConverter) conversion failed (%s)",
614 u_errorName(errorCode));
615 }
616
617 ucnv_close(cnv);
618 }
619 }
620 }
621
622 void
TestRemoveReplace()623 UnicodeStringTest::TestRemoveReplace()
624 {
625 UnicodeString test1("The rain in Spain stays mainly on the plain");
626 UnicodeString test2("eat SPAMburgers!");
627 UChar test3[] = { 0x53, 0x50, 0x41, 0x4d, 0x4d, 0 };
628 char test4[] = "SPAM";
629 UnicodeString& test5 = test1;
630
631 test1.replace(4, 4, test2, 4, 4);
632 test1.replace(12, 5, test3, 4);
633 test3[4] = 0;
634 test1.replace(17, 4, test3);
635 test1.replace(23, 4, test4);
636 test1.replaceBetween(37, 42, test2, 4, 8);
637
638 if (test1 != "The SPAM in SPAM SPAMs SPAMly on the SPAM")
639 errln("One of the replace methods failed:\n"
640 " expected \"The SPAM in SPAM SPAMs SPAMly on the SPAM\",\n"
641 " got \"" + test1 + "\"");
642
643 test1.remove(21, 1);
644 test1.removeBetween(26, 28);
645
646 if (test1 != "The SPAM in SPAM SPAM SPAM on the SPAM")
647 errln("One of the remove methods failed:\n"
648 " expected \"The SPAM in SPAM SPAM SPAM on the SPAM\",\n"
649 " got \"" + test1 + "\"");
650
651 for (int32_t i = 0; i < test1.length(); i++) {
652 if (test5[i] != 0x53 && test5[i] != 0x50 && test5[i] != 0x41 && test5[i] != 0x4d && test5[i] != 0x20) {
653 test1.setCharAt(i, 0x78);
654 }
655 }
656
657 if (test1 != "xxx SPAM xx SPAM SPAM SPAM xx xxx SPAM")
658 errln("One of the remove methods failed:\n"
659 " expected \"xxx SPAM xx SPAM SPAM SPAM xx xxx SPAM\",\n"
660 " got \"" + test1 + "\"");
661
662 test1.remove();
663 if (test1.length() != 0)
664 errln("Remove() failed: expected empty string, got \"" + test1 + "\"");
665 }
666
667 void
TestSearching()668 UnicodeStringTest::TestSearching()
669 {
670 UnicodeString test1("test test ttest tetest testesteststt");
671 UnicodeString test2("test");
672 UChar testChar = 0x74;
673
674 UChar32 testChar32 = 0x20402;
675 UChar testData[]={
676 // 0 1 2 3 4 5 6 7
677 0xd841, 0xdc02, 0x0071, 0xdc02, 0xd841, 0x0071, 0xd841, 0xdc02,
678
679 // 8 9 10 11 12 13 14 15
680 0x0071, 0x0072, 0xd841, 0xdc02, 0x0071, 0xd841, 0xdc02, 0x0071,
681
682 // 16 17 18 19
683 0xdc02, 0xd841, 0x0073, 0x0000
684 };
685 UnicodeString test3(testData);
686 UnicodeString test4(testChar32);
687
688 uint16_t occurrences = 0;
689 int32_t startPos = 0;
690 for ( ;
691 startPos != -1 && startPos < test1.length();
692 (startPos = test1.indexOf(test2, startPos)) != -1 ? (++occurrences, startPos += 4) : 0)
693 ;
694 if (occurrences != 6)
695 errln("indexOf failed: expected to find 6 occurrences, found " + occurrences);
696
697 for ( occurrences = 0, startPos = 10;
698 startPos != -1 && startPos < test1.length();
699 (startPos = test1.indexOf(test2, startPos)) != -1 ? (++occurrences, startPos += 4) : 0)
700 ;
701 if (occurrences != 4)
702 errln("indexOf with starting offset failed: expected to find 4 occurrences, found " + occurrences);
703
704 int32_t endPos = 28;
705 for ( occurrences = 0, startPos = 5;
706 startPos != -1 && startPos < test1.length();
707 (startPos = test1.indexOf(test2, startPos, endPos - startPos)) != -1 ? (++occurrences, startPos += 4) : 0)
708 ;
709 if (occurrences != 4)
710 errln("indexOf with starting and ending offsets failed: expected to find 4 occurrences, found " + occurrences);
711
712 //using UChar32 string
713 for ( startPos=0, occurrences=0;
714 startPos != -1 && startPos < test3.length();
715 (startPos = test3.indexOf(test4, startPos)) != -1 ? (++occurrences, startPos += 2) : 0)
716 ;
717 if (occurrences != 4)
718 errln((UnicodeString)"indexOf failed: expected to find 4 occurrences, found " + occurrences);
719
720 for ( startPos=10, occurrences=0;
721 startPos != -1 && startPos < test3.length();
722 (startPos = test3.indexOf(test4, startPos)) != -1 ? (++occurrences, startPos += 2) : 0)
723 ;
724 if (occurrences != 2)
725 errln("indexOf failed: expected to find 2 occurrences, found " + occurrences);
726 //---
727
728 for ( occurrences = 0, startPos = 0;
729 startPos != -1 && startPos < test1.length();
730 (startPos = test1.indexOf(testChar, startPos)) != -1 ? (++occurrences, startPos += 1) : 0)
731 ;
732 if (occurrences != 16)
733 errln("indexOf with character failed: expected to find 16 occurrences, found " + occurrences);
734
735 for ( occurrences = 0, startPos = 10;
736 startPos != -1 && startPos < test1.length();
737 (startPos = test1.indexOf(testChar, startPos)) != -1 ? (++occurrences, startPos += 1) : 0)
738 ;
739 if (occurrences != 12)
740 errln("indexOf with character & start offset failed: expected to find 12 occurrences, found " + occurrences);
741
742 for ( occurrences = 0, startPos = 5, endPos = 28;
743 startPos != -1 && startPos < test1.length();
744 (startPos = test1.indexOf(testChar, startPos, endPos - startPos)) != -1 ? (++occurrences, startPos += 1) : 0)
745 ;
746 if (occurrences != 10)
747 errln("indexOf with character & start & end offsets failed: expected to find 10 occurrences, found " + occurrences);
748
749 //testing for UChar32
750 UnicodeString subString;
751 for( occurrences =0, startPos=0; startPos < test3.length(); startPos +=1){
752 subString.append(test3, startPos, test3.length());
753 if(subString.indexOf(testChar32) != -1 ){
754 ++occurrences;
755 }
756 subString.remove();
757 }
758 if (occurrences != 14)
759 errln((UnicodeString)"indexOf failed: expected to find 14 occurrences, found " + occurrences);
760
761 for ( occurrences = 0, startPos = 0;
762 startPos != -1 && startPos < test3.length();
763 (startPos = test3.indexOf(testChar32, startPos)) != -1 ? (++occurrences, startPos += 1) : 0)
764 ;
765 if (occurrences != 4)
766 errln((UnicodeString)"indexOf failed: expected to find 4 occurrences, found " + occurrences);
767
768 endPos=test3.length();
769 for ( occurrences = 0, startPos = 5;
770 startPos != -1 && startPos < test3.length();
771 (startPos = test3.indexOf(testChar32, startPos, endPos - startPos)) != -1 ? (++occurrences, startPos += 1) : 0)
772 ;
773 if (occurrences != 3)
774 errln((UnicodeString)"indexOf with character & start & end offsets failed: expected to find 2 occurrences, found " + occurrences);
775 //---
776
777 if(test1.lastIndexOf(test2)!=29) {
778 errln("test1.lastIndexOf(test2)!=29");
779 }
780
781 if(test1.lastIndexOf(test2, 15)!=29 || test1.lastIndexOf(test2, 29)!=29 || test1.lastIndexOf(test2, 30)!=-1) {
782 errln("test1.lastIndexOf(test2, start) failed");
783 }
784
785 for ( occurrences = 0, startPos = 32;
786 startPos != -1;
787 (startPos = test1.lastIndexOf(test2, 5, startPos - 5)) != -1 ? ++occurrences : 0)
788 ;
789 if (occurrences != 4)
790 errln("lastIndexOf with starting and ending offsets failed: expected to find 4 occurrences, found " + occurrences);
791
792 for ( occurrences = 0, startPos = 32;
793 startPos != -1;
794 (startPos = test1.lastIndexOf(testChar, 5, startPos - 5)) != -1 ? ++occurrences : 0)
795 ;
796 if (occurrences != 11)
797 errln("lastIndexOf with character & start & end offsets failed: expected to find 11 occurrences, found " + occurrences);
798
799 //testing UChar32
800 startPos=test3.length();
801 for ( occurrences = 0;
802 startPos != -1;
803 (startPos = test3.lastIndexOf(testChar32, 5, startPos - 5)) != -1 ? ++occurrences : 0)
804 ;
805 if (occurrences != 3)
806 errln((UnicodeString)"lastIndexOf with character & start & end offsets failed: expected to find 3 occurrences, found " + occurrences);
807
808
809 for ( occurrences = 0, endPos = test3.length(); endPos > 0; endPos -= 1){
810 subString.remove();
811 subString.append(test3, 0, endPos);
812 if(subString.lastIndexOf(testChar32) != -1 ){
813 ++occurrences;
814 }
815 }
816 if (occurrences != 18)
817 errln((UnicodeString)"indexOf failed: expected to find 18 occurrences, found " + occurrences);
818 //---
819
820 // test that indexOf(UChar32) and lastIndexOf(UChar32)
821 // do not find surrogate code points when they are part of matched pairs
822 // (= part of supplementary code points)
823 // Jitterbug 1542
824 if(test3.indexOf((UChar32)0xd841) != 4 || test3.indexOf((UChar32)0xdc02) != 3) {
825 errln("error: UnicodeString::indexOf(UChar32 surrogate) finds a partial supplementary code point");
826 }
827 if( UnicodeString(test3, 0, 17).lastIndexOf((UChar)0xd841, 0) != 4 ||
828 UnicodeString(test3, 0, 17).lastIndexOf((UChar32)0xd841, 2) != 4 ||
829 test3.lastIndexOf((UChar32)0xd841, 0, 17) != 4 || test3.lastIndexOf((UChar32)0xdc02, 0, 17) != 16
830 ) {
831 errln("error: UnicodeString::lastIndexOf(UChar32 surrogate) finds a partial supplementary code point");
832 }
833 }
834
835 void
TestSpacePadding()836 UnicodeStringTest::TestSpacePadding()
837 {
838 UnicodeString test1("hello");
839 UnicodeString test2(" there");
840 UnicodeString test3("Hi! How ya doin'? Beautiful day, isn't it?");
841 UnicodeString test4;
842 UBool returnVal;
843 UnicodeString expectedValue;
844
845 returnVal = test1.padLeading(15);
846 expectedValue = " hello";
847 if (returnVal == FALSE || test1 != expectedValue)
848 errln("padLeading() failed: expected \"" + expectedValue + "\", got \"" + test1 + "\".");
849
850 returnVal = test2.padTrailing(15);
851 expectedValue = " there ";
852 if (returnVal == FALSE || test2 != expectedValue)
853 errln("padTrailing() failed: expected \"" + expectedValue + "\", got \"" + test2 + "\".");
854
855 expectedValue = test3;
856 returnVal = test3.padTrailing(15);
857 if (returnVal == TRUE || test3 != expectedValue)
858 errln("padTrailing() failed: expected \"" + expectedValue + "\", got \"" + test3 + "\".");
859
860 expectedValue = "hello";
861 test4.setTo(test1).trim();
862
863 if (test4 != expectedValue || test1 == expectedValue || test4 != expectedValue)
864 errln("trim(UnicodeString&) failed");
865
866 test1.trim();
867 if (test1 != expectedValue)
868 errln("trim() failed: expected \"" + expectedValue + "\", got \"" + test1 + "\".");
869
870 test2.trim();
871 expectedValue = "there";
872 if (test2 != expectedValue)
873 errln("trim() failed: expected \"" + expectedValue + "\", got \"" + test2 + "\".");
874
875 test3.trim();
876 expectedValue = "Hi! How ya doin'? Beautiful day, isn't it?";
877 if (test3 != expectedValue)
878 errln("trim() failed: expected \"" + expectedValue + "\", got \"" + test3 + "\".");
879
880 returnVal = test1.truncate(15);
881 expectedValue = "hello";
882 if (returnVal == TRUE || test1 != expectedValue)
883 errln("truncate() failed: expected \"" + expectedValue + "\", got \"" + test1 + "\".");
884
885 returnVal = test2.truncate(15);
886 expectedValue = "there";
887 if (returnVal == TRUE || test2 != expectedValue)
888 errln("truncate() failed: expected \"" + expectedValue + "\", got \"" + test2 + "\".");
889
890 returnVal = test3.truncate(15);
891 expectedValue = "Hi! How ya doi";
892 if (returnVal == FALSE || test3 != expectedValue)
893 errln("truncate() failed: expected \"" + expectedValue + "\", got \"" + test3 + "\".");
894 }
895
896 void
TestPrefixAndSuffix()897 UnicodeStringTest::TestPrefixAndSuffix()
898 {
899 UnicodeString test1("Now is the time for all good men to come to the aid of their country.");
900 UnicodeString test2("Now");
901 UnicodeString test3("country.");
902 UnicodeString test4("count");
903
904 if (!test1.startsWith(test2) || !test1.startsWith(test2, 0, test2.length())) {
905 errln("startsWith() failed: \"" + test2 + "\" should be a prefix of \"" + test1 + "\".");
906 }
907
908 if (test1.startsWith(test3) ||
909 test1.startsWith(test3.getBuffer(), test3.length()) ||
910 test1.startsWith(test3.getTerminatedBuffer(), 0, -1)
911 ) {
912 errln("startsWith() failed: \"" + test3 + "\" shouldn't be a prefix of \"" + test1 + "\".");
913 }
914
915 if (test1.endsWith(test2)) {
916 errln("endsWith() failed: \"" + test2 + "\" shouldn't be a suffix of \"" + test1 + "\".");
917 }
918
919 if (!test1.endsWith(test3)) {
920 errln("endsWith(test3) failed: \"" + test3 + "\" should be a suffix of \"" + test1 + "\".");
921 }
922 if (!test1.endsWith(test3, 0, INT32_MAX)) {
923 errln("endsWith(test3, 0, INT32_MAX) failed: \"" + test3 + "\" should be a suffix of \"" + test1 + "\".");
924 }
925
926 if(!test1.endsWith(test3.getBuffer(), test3.length())) {
927 errln("endsWith(test3.getBuffer(), test3.length()) failed: \"" + test3 + "\" should be a suffix of \"" + test1 + "\".");
928 }
929 if(!test1.endsWith(test3.getTerminatedBuffer(), 0, -1)) {
930 errln("endsWith(test3.getTerminatedBuffer(), 0, -1) failed: \"" + test3 + "\" should be a suffix of \"" + test1 + "\".");
931 }
932
933 if (!test3.startsWith(test4)) {
934 errln("endsWith(test4) failed: \"" + test4 + "\" should be a prefix of \"" + test3 + "\".");
935 }
936
937 if (test4.startsWith(test3)) {
938 errln("startsWith(test3) failed: \"" + test3 + "\" shouldn't be a prefix of \"" + test4 + "\".");
939 }
940 }
941
942 void
TestFindAndReplace()943 UnicodeStringTest::TestFindAndReplace()
944 {
945 UnicodeString test1("One potato, two potato, three potato, four\n");
946 UnicodeString test2("potato");
947 UnicodeString test3("MISSISSIPPI");
948
949 UnicodeString expectedValue;
950
951 test1.findAndReplace(test2, test3);
952 expectedValue = "One MISSISSIPPI, two MISSISSIPPI, three MISSISSIPPI, four\n";
953 if (test1 != expectedValue)
954 errln("findAndReplace failed: expected \"" + expectedValue + "\", got \"" + test1 + "\".");
955 test1.findAndReplace(2, 32, test3, test2);
956 expectedValue = "One potato, two potato, three MISSISSIPPI, four\n";
957 if (test1 != expectedValue)
958 errln("findAndReplace failed: expected \"" + expectedValue + "\", got \"" + test1 + "\".");
959 }
960
961 void
TestReverse()962 UnicodeStringTest::TestReverse()
963 {
964 UnicodeString test("backwards words say to used I");
965
966 test.reverse();
967 test.reverse(2, 4);
968 test.reverse(7, 2);
969 test.reverse(10, 3);
970 test.reverse(14, 5);
971 test.reverse(20, 9);
972
973 if (test != "I used to say words backwards")
974 errln("reverse() failed: Expected \"I used to say words backwards\",\n got \""
975 + test + "\"");
976
977 test=UNICODE_STRING("\\U0002f999\\U0001d15f\\u00c4\\u1ed0", 32).unescape();
978 test.reverse();
979 if(test.char32At(0)!=0x1ed0 || test.char32At(1)!=0xc4 || test.char32At(2)!=0x1d15f || test.char32At(4)!=0x2f999) {
980 errln("reverse() failed with supplementary characters");
981 }
982 }
983
984 void
TestMiscellaneous()985 UnicodeStringTest::TestMiscellaneous()
986 {
987 UnicodeString test1("This is a test");
988 UnicodeString test2("This is a test");
989 UnicodeString test3("Me too!");
990
991 // test getBuffer(minCapacity) and releaseBuffer()
992 test1=UnicodeString(); // make sure that it starts with its stackBuffer
993 UChar *p=test1.getBuffer(20);
994 if(test1.getCapacity()<20) {
995 errln("UnicodeString::getBuffer(20).getCapacity()<20");
996 }
997
998 test1.append((UChar)7); // must not be able to modify the string here
999 test1.setCharAt(3, 7);
1000 test1.reverse();
1001 if( test1.length()!=0 ||
1002 test1.charAt(0)!=0xffff || test1.charAt(3)!=0xffff ||
1003 test1.getBuffer(10)!=0 || test1.getBuffer()!=0
1004 ) {
1005 errln("UnicodeString::getBuffer(minCapacity) allows read or write access to the UnicodeString");
1006 }
1007
1008 p[0]=1;
1009 p[1]=2;
1010 p[2]=3;
1011 test1.releaseBuffer(3);
1012 test1.append((UChar)4);
1013
1014 if(test1.length()!=4 || test1.charAt(0)!=1 || test1.charAt(1)!=2 || test1.charAt(2)!=3 || test1.charAt(3)!=4) {
1015 errln("UnicodeString::releaseBuffer(newLength) does not properly reallow access to the UnicodeString");
1016 }
1017
1018 // test releaseBuffer() without getBuffer(minCapacity) - must not have any effect
1019 test1.releaseBuffer(1);
1020 if(test1.length()!=4 || test1.charAt(0)!=1 || test1.charAt(1)!=2 || test1.charAt(2)!=3 || test1.charAt(3)!=4) {
1021 errln("UnicodeString::releaseBuffer(newLength) without getBuffer(minCapacity) changed the UnicodeString");
1022 }
1023
1024 // test getBuffer(const)
1025 const UChar *q=test1.getBuffer(), *r=test1.getBuffer();
1026 if( test1.length()!=4 ||
1027 q[0]!=1 || q[1]!=2 || q[2]!=3 || q[3]!=4 ||
1028 r[0]!=1 || r[1]!=2 || r[2]!=3 || r[3]!=4
1029 ) {
1030 errln("UnicodeString::getBuffer(const) does not return a usable buffer pointer");
1031 }
1032
1033 // test releaseBuffer() with a NUL-terminated buffer
1034 test1.getBuffer(20)[2]=0;
1035 test1.releaseBuffer(); // implicit -1
1036 if(test1.length()!=2 || test1.charAt(0)!=1 || test1.charAt(1) !=2) {
1037 errln("UnicodeString::releaseBuffer(-1) does not properly set the length of the UnicodeString");
1038 }
1039
1040 // test releaseBuffer() with a non-NUL-terminated buffer
1041 p=test1.getBuffer(256);
1042 for(int32_t i=0; i<test1.getCapacity(); ++i) {
1043 p[i]=(UChar)1; // fill the buffer with all non-NUL code units
1044 }
1045 test1.releaseBuffer(); // implicit -1
1046 if(test1.length()!=test1.getCapacity() || test1.charAt(1)!=1 || test1.charAt(100)!=1 || test1.charAt(test1.getCapacity()-1)!=1) {
1047 errln("UnicodeString::releaseBuffer(-1 but no NUL) does not properly set the length of the UnicodeString");
1048 }
1049
1050 // test getTerminatedBuffer()
1051 test1=UnicodeString("This is another test.", "");
1052 test2=UnicodeString("This is another test.", "");
1053 q=test1.getTerminatedBuffer();
1054 if(q[test1.length()]!=0 || test1!=test2 || test2.compare(q, -1)!=0) {
1055 errln("getTerminatedBuffer()[length]!=0");
1056 }
1057
1058 const UChar u[]={ 5, 6, 7, 8, 0 };
1059 test1.setTo(FALSE, u, 3);
1060 q=test1.getTerminatedBuffer();
1061 if(q==u || q[0]!=5 || q[1]!=6 || q[2]!=7 || q[3]!=0) {
1062 errln("UnicodeString(u[3]).getTerminatedBuffer() returns a bad buffer");
1063 }
1064
1065 test1.setTo(TRUE, u, -1);
1066 q=test1.getTerminatedBuffer();
1067 if(q!=u || test1.length()!=4 || q[3]!=8 || q[4]!=0) {
1068 errln("UnicodeString(u[-1]).getTerminatedBuffer() returns a bad buffer");
1069 }
1070
1071 test1=UNICODE_STRING("la", 2);
1072 test1.append(UNICODE_STRING(" lila", 5).getTerminatedBuffer(), 0, -1);
1073 if(test1!=UNICODE_STRING("la lila", 7)) {
1074 errln("UnicodeString::append(const UChar *, start, length) failed");
1075 }
1076
1077 test1.insert(3, UNICODE_STRING("dudum ", 6), 0, INT32_MAX);
1078 if(test1!=UNICODE_STRING("la dudum lila", 13)) {
1079 errln("UnicodeString::insert(start, const UniStr &, start, length) failed");
1080 }
1081
1082 static const UChar ucs[]={ 0x68, 0x6d, 0x20, 0 };
1083 test1.insert(9, ucs, -1);
1084 if(test1!=UNICODE_STRING("la dudum hm lila", 16)) {
1085 errln("UnicodeString::insert(start, const UChar *, length) failed");
1086 }
1087
1088 test1.replace(9, 2, (UChar)0x2b);
1089 if(test1!=UNICODE_STRING("la dudum + lila", 15)) {
1090 errln("UnicodeString::replace(start, length, UChar) failed");
1091 }
1092
1093 if(test1.hasMetaData() || UnicodeString().hasMetaData()) {
1094 errln("UnicodeString::hasMetaData() returns TRUE");
1095 }
1096 }
1097
1098 void
TestStackAllocation()1099 UnicodeStringTest::TestStackAllocation()
1100 {
1101 UChar testString[] ={
1102 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x63, 0x72, 0x61, 0x7a, 0x79, 0x20, 0x74, 0x65, 0x73, 0x74, 0x2e, 0 };
1103 UChar guardWord = 0x4DED;
1104 UnicodeString* test = 0;
1105
1106 test = new UnicodeString(testString);
1107 if (*test != "This is a crazy test.")
1108 errln("Test string failed to initialize properly.");
1109 if (guardWord != 0x04DED)
1110 errln("Test string initialization overwrote guard word!");
1111
1112 test->insert(8, "only ");
1113 test->remove(15, 6);
1114 if (*test != "This is only a test.")
1115 errln("Manipulation of test string failed to work right.");
1116 if (guardWord != 0x4DED)
1117 errln("Manipulation of test string overwrote guard word!");
1118
1119 // we have to deinitialize and release the backing store by calling the destructor
1120 // explicitly, since we can't overload operator delete
1121 delete test;
1122
1123 UChar workingBuffer[] = {
1124 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20,
1125 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6d, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20,
1126 0x63, 0x6f, 0x6d, 0x65, 0xffff, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1128 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1129 UChar guardWord2 = 0x4DED;
1130
1131 test = new UnicodeString(workingBuffer, 35, 100);
1132 if (*test != "Now is the time for all men to come")
1133 errln("Stack-allocated backing store failed to initialize correctly.");
1134 if (guardWord2 != 0x4DED)
1135 errln("Stack-allocated backing store overwrote guard word!");
1136
1137 test->insert(24, "good ");
1138 if (*test != "Now is the time for all good men to come")
1139 errln("insert() on stack-allocated UnicodeString didn't work right");
1140 if (guardWord2 != 0x4DED)
1141 errln("insert() on stack-allocated UnicodeString overwrote guard word!");
1142
1143 if (workingBuffer[24] != 0x67)
1144 errln("insert() on stack-allocated UnicodeString didn't affect backing store");
1145
1146 *test += " to the aid of their country.";
1147 if (*test != "Now is the time for all good men to come to the aid of their country.")
1148 errln("Stack-allocated UnicodeString overflow didn't work");
1149 if (guardWord2 != 0x4DED)
1150 errln("Stack-allocated UnicodeString overflow overwrote guard word!");
1151
1152 *test = "ha!";
1153 if (*test != "ha!")
1154 errln("Assignment to stack-allocated UnicodeString didn't work");
1155 if (workingBuffer[0] != 0x4e)
1156 errln("Change to UnicodeString after overflow are still affecting original buffer");
1157 if (guardWord2 != 0x4DED)
1158 errln("Change to UnicodeString after overflow overwrote guard word!");
1159
1160 // test read-only aliasing with setTo()
1161 workingBuffer[0] = 0x20ac;
1162 workingBuffer[1] = 0x125;
1163 workingBuffer[2] = 0;
1164 test->setTo(TRUE, workingBuffer, 2);
1165 if(test->length() != 2 || test->charAt(0) != 0x20ac || test->charAt(1) != 0x125) {
1166 errln("UnicodeString.setTo(readonly alias) does not alias correctly");
1167 }
1168
1169 UnicodeString *c=(UnicodeString *)test->clone();
1170
1171 workingBuffer[1] = 0x109;
1172 if(test->charAt(1) != 0x109) {
1173 errln("UnicodeString.setTo(readonly alias) made a copy: did not see change in buffer");
1174 }
1175
1176 if(c->length() != 2 || c->charAt(1) != 0x125) {
1177 errln("clone(alias) did not copy the buffer");
1178 }
1179 delete c;
1180
1181 test->setTo(TRUE, workingBuffer, -1);
1182 if(test->length() != 2 || test->charAt(0) != 0x20ac || test->charAt(1) != 0x109) {
1183 errln("UnicodeString.setTo(readonly alias, length -1) does not alias correctly");
1184 }
1185
1186 test->setTo(FALSE, workingBuffer, -1);
1187 if(!test->isBogus()) {
1188 errln("UnicodeString.setTo(unterminated readonly alias, length -1) does not result in isBogus()");
1189 }
1190
1191 delete test;
1192
1193 test=new UnicodeString();
1194 UChar buffer[]={0x0061, 0x0062, 0x20ac, 0x0043, 0x0042, 0x0000};
1195 test->setTo(buffer, 4, 10);
1196 if(test->length() !=4 || test->charAt(0) != 0x0061 || test->charAt(1) != 0x0062 ||
1197 test->charAt(2) != 0x20ac || test->charAt(3) != 0x0043){
1198 errln((UnicodeString)"UnicodeString.setTo(UChar*, length, capacity) does not work correctly\n" + prettify(*test));
1199 }
1200 delete test;
1201
1202
1203 // test the UChar32 constructor
1204 UnicodeString c32Test((UChar32)0x10ff2a);
1205 if( c32Test.length() != UTF_CHAR_LENGTH(0x10ff2a) ||
1206 c32Test.char32At(c32Test.length() - 1) != 0x10ff2a
1207 ) {
1208 errln("The UnicodeString(UChar32) constructor does not work with a 0x10ff2a filler");
1209 }
1210
1211 // test the (new) capacity constructor
1212 UnicodeString capTest(5, (UChar32)0x2a, 5);
1213 if( capTest.length() != 5 * UTF_CHAR_LENGTH(0x2a) ||
1214 capTest.char32At(0) != 0x2a ||
1215 capTest.char32At(4) != 0x2a
1216 ) {
1217 errln("The UnicodeString capacity constructor does not work with an ASCII filler");
1218 }
1219
1220 capTest = UnicodeString(5, (UChar32)0x10ff2a, 5);
1221 if( capTest.length() != 5 * UTF_CHAR_LENGTH(0x10ff2a) ||
1222 capTest.char32At(0) != 0x10ff2a ||
1223 capTest.char32At(4) != 0x10ff2a
1224 ) {
1225 errln("The UnicodeString capacity constructor does not work with a 0x10ff2a filler");
1226 }
1227
1228 capTest = UnicodeString(5, (UChar32)0, 0);
1229 if(capTest.length() != 0) {
1230 errln("The UnicodeString capacity constructor does not work with a 0x10ff2a filler");
1231 }
1232 }
1233
1234 /**
1235 * Test the unescape() function.
1236 */
TestUnescape(void)1237 void UnicodeStringTest::TestUnescape(void) {
1238 UnicodeString IN("abc\\u4567 \\n\\r \\U00101234xyz\\x1\\x{5289}\\x1b");
1239 UnicodeString OUT("abc");
1240 OUT.append((UChar)0x4567);
1241 OUT.append(" ");
1242 OUT.append((UChar)0xA);
1243 OUT.append((UChar)0xD);
1244 OUT.append(" ");
1245 OUT.append((UChar32)0x00101234);
1246 OUT.append("xyz");
1247 OUT.append((UChar32)1).append((UChar32)0x5289).append((UChar)0x1b);
1248 UnicodeString result = IN.unescape();
1249 if (result != OUT) {
1250 errln("FAIL: " + prettify(IN) + ".unescape() -> " +
1251 prettify(result) + ", expected " +
1252 prettify(OUT));
1253 }
1254
1255 // test that an empty string is returned in case of an error
1256 if (!UNICODE_STRING("wrong \\u sequence", 17).unescape().isEmpty()) {
1257 errln("FAIL: unescaping of a string with an illegal escape sequence did not return an empty string");
1258 }
1259 }
1260
1261 /* test code point counting functions --------------------------------------- */
1262
1263 /* reference implementation of UnicodeString::hasMoreChar32Than() */
1264 static int32_t
_refUnicodeStringHasMoreChar32Than(const UnicodeString & s,int32_t start,int32_t length,int32_t number)1265 _refUnicodeStringHasMoreChar32Than(const UnicodeString &s, int32_t start, int32_t length, int32_t number) {
1266 int32_t count=s.countChar32(start, length);
1267 return count>number;
1268 }
1269
1270 /* compare the real function against the reference */
1271 void
_testUnicodeStringHasMoreChar32Than(const UnicodeString & s,int32_t start,int32_t length,int32_t number)1272 UnicodeStringTest::_testUnicodeStringHasMoreChar32Than(const UnicodeString &s, int32_t start, int32_t length, int32_t number) {
1273 if(s.hasMoreChar32Than(start, length, number)!=_refUnicodeStringHasMoreChar32Than(s, start, length, number)) {
1274 errln("hasMoreChar32Than(%d, %d, %d)=%hd is wrong\n",
1275 start, length, number, s.hasMoreChar32Than(start, length, number));
1276 }
1277 }
1278
1279 void
TestCountChar32(void)1280 UnicodeStringTest::TestCountChar32(void) {
1281 {
1282 UnicodeString s=UNICODE_STRING("\\U0002f999\\U0001d15f\\u00c4\\u1ed0", 32).unescape();
1283
1284 // test countChar32()
1285 // note that this also calls and tests u_countChar32(length>=0)
1286 if(
1287 s.countChar32()!=4 ||
1288 s.countChar32(1)!=4 ||
1289 s.countChar32(2)!=3 ||
1290 s.countChar32(2, 3)!=2 ||
1291 s.countChar32(2, 0)!=0
1292 ) {
1293 errln("UnicodeString::countChar32() failed");
1294 }
1295
1296 // NUL-terminate the string buffer and test u_countChar32(length=-1)
1297 const UChar *buffer=s.getTerminatedBuffer();
1298 if(
1299 u_countChar32(buffer, -1)!=4 ||
1300 u_countChar32(buffer+1, -1)!=4 ||
1301 u_countChar32(buffer+2, -1)!=3 ||
1302 u_countChar32(buffer+3, -1)!=3 ||
1303 u_countChar32(buffer+4, -1)!=2 ||
1304 u_countChar32(buffer+5, -1)!=1 ||
1305 u_countChar32(buffer+6, -1)!=0
1306 ) {
1307 errln("u_countChar32(length=-1) failed");
1308 }
1309
1310 // test u_countChar32() with bad input
1311 if(u_countChar32(NULL, 5)!=0 || u_countChar32(buffer, -2)!=0) {
1312 errln("u_countChar32(bad input) failed (returned non-zero counts)");
1313 }
1314 }
1315
1316 /* test data and variables for hasMoreChar32Than() */
1317 static const UChar str[]={
1318 0x61, 0x62, 0xd800, 0xdc00,
1319 0xd801, 0xdc01, 0x63, 0xd802,
1320 0x64, 0xdc03, 0x65, 0x66,
1321 0xd804, 0xdc04, 0xd805, 0xdc05,
1322 0x67
1323 };
1324 UnicodeString string(str, LENGTHOF(str));
1325 int32_t start, length, number;
1326
1327 /* test hasMoreChar32Than() */
1328 for(length=string.length(); length>=0; --length) {
1329 for(start=0; start<=length; ++start) {
1330 for(number=-1; number<=((length-start)+2); ++number) {
1331 _testUnicodeStringHasMoreChar32Than(string, start, length-start, number);
1332 }
1333 }
1334 }
1335
1336 /* test hasMoreChar32Than() with pinning */
1337 for(start=-1; start<=string.length()+1; ++start) {
1338 for(number=-1; number<=((string.length()-start)+2); ++number) {
1339 _testUnicodeStringHasMoreChar32Than(string, start, 0x7fffffff, number);
1340 }
1341 }
1342
1343 /* test hasMoreChar32Than() with a bogus string */
1344 string.setToBogus();
1345 for(length=-1; length<=1; ++length) {
1346 for(start=-1; start<=length; ++start) {
1347 for(number=-1; number<=((length-start)+2); ++number) {
1348 _testUnicodeStringHasMoreChar32Than(string, start, length-start, number);
1349 }
1350 }
1351 }
1352 }
1353
1354 void
TestBogus()1355 UnicodeStringTest::TestBogus() {
1356 UnicodeString test1("This is a test");
1357 UnicodeString test2("This is a test");
1358 UnicodeString test3("Me too!");
1359
1360 // test isBogus() and setToBogus()
1361 if (test1.isBogus() || test2.isBogus() || test3.isBogus()) {
1362 errln("A string returned TRUE for isBogus()!");
1363 }
1364
1365 // NULL pointers are treated like empty strings
1366 // use other illegal arguments to make a bogus string
1367 test3.setTo(FALSE, test1.getBuffer(), -2);
1368 if(!test3.isBogus()) {
1369 errln("A bogus string returned FALSE for isBogus()!");
1370 }
1371 if (test1.hashCode() != test2.hashCode() || test1.hashCode() == test3.hashCode()) {
1372 errln("hashCode() failed");
1373 }
1374 if(test3.getBuffer()!=0 || test3.getBuffer(20)!=0 || test3.getTerminatedBuffer()!=0) {
1375 errln("bogus.getBuffer()!=0");
1376 }
1377 if (test1.indexOf(test3) != -1) {
1378 errln("bogus.indexOf() != -1");
1379 }
1380 if (test1.lastIndexOf(test3) != -1) {
1381 errln("bogus.lastIndexOf() != -1");
1382 }
1383 if (test1.caseCompare(test3, U_FOLD_CASE_DEFAULT) != 1 || test3.caseCompare(test1, U_FOLD_CASE_DEFAULT) != -1) {
1384 errln("caseCompare() doesn't work with bogus strings");
1385 }
1386 if (test1.compareCodePointOrder(test3) != 1 || test3.compareCodePointOrder(test1) != -1) {
1387 errln("compareCodePointOrder() doesn't work with bogus strings");
1388 }
1389
1390 // verify that non-assignment modifications fail and do not revive a bogus string
1391 test3.setToBogus();
1392 test3.append((UChar)0x61);
1393 if(!test3.isBogus() || test3.getBuffer()!=0) {
1394 errln("bogus.append('a') worked but must not");
1395 }
1396
1397 test3.setToBogus();
1398 test3.findAndReplace(UnicodeString((UChar)0x61), test2);
1399 if(!test3.isBogus() || test3.getBuffer()!=0) {
1400 errln("bogus.findAndReplace() worked but must not");
1401 }
1402
1403 test3.setToBogus();
1404 test3.trim();
1405 if(!test3.isBogus() || test3.getBuffer()!=0) {
1406 errln("bogus.trim() revived bogus but must not");
1407 }
1408
1409 test3.setToBogus();
1410 test3.remove(1);
1411 if(!test3.isBogus() || test3.getBuffer()!=0) {
1412 errln("bogus.remove(1) revived bogus but must not");
1413 }
1414
1415 test3.setToBogus();
1416 if(!test3.setCharAt(0, 0x62).isBogus() || !test3.isEmpty()) {
1417 errln("bogus.setCharAt(0, 'b') worked but must not");
1418 }
1419
1420 test3.setToBogus();
1421 if(test3.truncate(1) || !test3.isBogus() || !test3.isEmpty()) {
1422 errln("bogus.truncate(1) revived bogus but must not");
1423 }
1424
1425 // verify that assignments revive a bogus string
1426 test3.setToBogus();
1427 if(!test3.isBogus() || (test3=test1).isBogus() || test3!=test1) {
1428 errln("bogus.operator=() failed");
1429 }
1430
1431 test3.setToBogus();
1432 if(!test3.isBogus() || test3.fastCopyFrom(test1).isBogus() || test3!=test1) {
1433 errln("bogus.fastCopyFrom() failed");
1434 }
1435
1436 test3.setToBogus();
1437 if(!test3.isBogus() || test3.setTo(test1).isBogus() || test3!=test1) {
1438 errln("bogus.setTo(UniStr) failed");
1439 }
1440
1441 test3.setToBogus();
1442 if(!test3.isBogus() || test3.setTo(test1, 0).isBogus() || test3!=test1) {
1443 errln("bogus.setTo(UniStr, 0) failed");
1444 }
1445
1446 test3.setToBogus();
1447 if(!test3.isBogus() || test3.setTo(test1, 0, 0x7fffffff).isBogus() || test3!=test1) {
1448 errln("bogus.setTo(UniStr, 0, len) failed");
1449 }
1450
1451 test3.setToBogus();
1452 if(!test3.isBogus() || test3.setTo(test1.getBuffer(), test1.length()).isBogus() || test3!=test1) {
1453 errln("bogus.setTo(const UChar *, len) failed");
1454 }
1455
1456 test3.setToBogus();
1457 if(!test3.isBogus() || test3.setTo((UChar)0x2028).isBogus() || test3!=UnicodeString((UChar)0x2028)) {
1458 errln("bogus.setTo(UChar) failed");
1459 }
1460
1461 test3.setToBogus();
1462 if(!test3.isBogus() || test3.setTo((UChar32)0x1d157).isBogus() || test3!=UnicodeString((UChar32)0x1d157)) {
1463 errln("bogus.setTo(UChar32) failed");
1464 }
1465
1466 test3.setToBogus();
1467 if(!test3.isBogus() || test3.setTo(FALSE, test1.getBuffer(), test1.length()).isBogus() || test3!=test1) {
1468 errln("bogus.setTo(readonly alias) failed");
1469 }
1470
1471 // writable alias to another string's buffer: very bad idea, just convenient for this test
1472 test3.setToBogus();
1473 if(!test3.isBogus() || test3.setTo((UChar *)test1.getBuffer(), test1.length(), test1.getCapacity()).isBogus() || test3!=test1) {
1474 errln("bogus.setTo(writable alias) failed");
1475 }
1476
1477 // verify simple, documented ways to turn a bogus string into an empty one
1478 test3.setToBogus();
1479 if(!test3.isBogus() || (test3=UnicodeString()).isBogus() || !test3.isEmpty()) {
1480 errln("bogus.operator=(UnicodeString()) failed");
1481 }
1482
1483 test3.setToBogus();
1484 if(!test3.isBogus() || test3.setTo(UnicodeString()).isBogus() || !test3.isEmpty()) {
1485 errln("bogus.setTo(UnicodeString()) failed");
1486 }
1487
1488 test3.setToBogus();
1489 if(test3.remove().isBogus() || test3.getBuffer()==0 || !test3.isEmpty()) {
1490 errln("bogus.remove() failed");
1491 }
1492
1493 test3.setToBogus();
1494 if(test3.remove(0, INT32_MAX).isBogus() || test3.getBuffer()==0 || !test3.isEmpty()) {
1495 errln("bogus.remove(0, INT32_MAX) failed");
1496 }
1497
1498 test3.setToBogus();
1499 if(test3.truncate(0) || test3.isBogus() || !test3.isEmpty()) {
1500 errln("bogus.truncate(0) failed");
1501 }
1502
1503 test3.setToBogus();
1504 if(!test3.isBogus() || test3.setTo((UChar32)-1).isBogus() || !test3.isEmpty()) {
1505 errln("bogus.setTo((UChar32)-1) failed");
1506 }
1507
1508 static const UChar nul=0;
1509
1510 test3.setToBogus();
1511 if(!test3.isBogus() || test3.setTo(&nul, 0).isBogus() || !test3.isEmpty()) {
1512 errln("bogus.setTo(&nul, 0) failed");
1513 }
1514
1515 test3.setToBogus();
1516 if(!test3.isBogus() || test3.getBuffer()!=0) {
1517 errln("setToBogus() failed to make a string bogus");
1518 }
1519
1520 test3.setToBogus();
1521 if(test1.isBogus() || !(test1=test3).isBogus()) {
1522 errln("normal=bogus failed to make the left string bogus");
1523 }
1524
1525 // test that NULL primitive input string values are treated like
1526 // empty strings, not errors (bogus)
1527 test2.setTo((UChar32)0x10005);
1528 if(test2.insert(1, NULL, 1).length()!=2) {
1529 errln("UniStr.insert(...NULL...) should not modify the string but does");
1530 }
1531
1532 UErrorCode errorCode=U_ZERO_ERROR;
1533 UnicodeString
1534 test4((const UChar *)NULL),
1535 test5(TRUE, (const UChar *)NULL, 1),
1536 test6((UChar *)NULL, 5, 5),
1537 test7((const char *)NULL, 3, NULL, errorCode);
1538 if(test4.isBogus() || test5.isBogus() || test6.isBogus() || test7.isBogus()) {
1539 errln("a constructor set to bogus for a NULL input string, should be empty");
1540 }
1541
1542 test4.setTo(NULL, 3);
1543 test5.setTo(TRUE, (const UChar *)NULL, 1);
1544 test6.setTo((UChar *)NULL, 5, 5);
1545 if(test4.isBogus() || test5.isBogus() || test6.isBogus()) {
1546 errln("a setTo() set to bogus for a NULL input string, should be empty");
1547 }
1548
1549 // test that bogus==bogus<any
1550 if(test1!=test3 || test1.compare(test3)!=0) {
1551 errln("bogus==bogus failed");
1552 }
1553
1554 test2.remove();
1555 if(test1>=test2 || !(test2>test1) || test1.compare(test2)>=0 || !(test2.compare(test1)>0)) {
1556 errln("bogus<empty failed");
1557 }
1558 }
1559
1560 // StringEnumeration ------------------------------------------------------- ***
1561 // most of StringEnumeration is tested elsewhere
1562 // this test improves code coverage
1563
1564 static const char *const
1565 testEnumStrings[]={
1566 "a",
1567 "b",
1568 "c",
1569 "this is a long string which helps us test some buffer limits",
1570 "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
1571 };
1572
1573 class TestEnumeration : public StringEnumeration {
1574 public:
TestEnumeration()1575 TestEnumeration() : i(0) {}
1576
count(UErrorCode &) const1577 virtual int32_t count(UErrorCode& /*status*/) const {
1578 return LENGTHOF(testEnumStrings);
1579 }
1580
snext(UErrorCode & status)1581 virtual const UnicodeString *snext(UErrorCode &status) {
1582 if(U_SUCCESS(status) && i<LENGTHOF(testEnumStrings)) {
1583 unistr=UnicodeString(testEnumStrings[i++], "");
1584 return &unistr;
1585 }
1586
1587 return NULL;
1588 }
1589
reset(UErrorCode &)1590 virtual void reset(UErrorCode& /*status*/) {
1591 i=0;
1592 }
1593
getStaticClassID()1594 static inline UClassID getStaticClassID() {
1595 return (UClassID)&fgClassID;
1596 }
getDynamicClassID() const1597 virtual UClassID getDynamicClassID() const {
1598 return getStaticClassID();
1599 }
1600
1601 private:
1602 static const char fgClassID;
1603
1604 int32_t i, length;
1605 };
1606
1607 const char TestEnumeration::fgClassID=0;
1608
1609 void
TestStringEnumeration()1610 UnicodeStringTest::TestStringEnumeration() {
1611 UnicodeString s;
1612 TestEnumeration ten;
1613 int32_t i, length;
1614 UErrorCode status;
1615
1616 const UChar *pu;
1617 const char *pc;
1618
1619 // test the next() default implementation and ensureCharsCapacity()
1620 for(i=0; i<LENGTHOF(testEnumStrings); ++i) {
1621 status=U_ZERO_ERROR;
1622 pc=ten.next(&length, status);
1623 s=UnicodeString(testEnumStrings[i], "");
1624 if(U_FAILURE(status) || pc==NULL || length!=s.length() || UnicodeString(pc, length, "")!=s) {
1625 errln("StringEnumeration.next(%d) failed", i);
1626 }
1627 }
1628 status=U_ZERO_ERROR;
1629 if(ten.next(&length, status)!=NULL) {
1630 errln("StringEnumeration.next(done)!=NULL");
1631 }
1632
1633 // test the unext() default implementation
1634 ten.reset(status);
1635 for(i=0; i<LENGTHOF(testEnumStrings); ++i) {
1636 status=U_ZERO_ERROR;
1637 pu=ten.unext(&length, status);
1638 s=UnicodeString(testEnumStrings[i], "");
1639 if(U_FAILURE(status) || pu==NULL || length!=s.length() || UnicodeString(TRUE, pu, length)!=s) {
1640 errln("StringEnumeration.unext(%d) failed", i);
1641 }
1642 }
1643 status=U_ZERO_ERROR;
1644 if(ten.unext(&length, status)!=NULL) {
1645 errln("StringEnumeration.unext(done)!=NULL");
1646 }
1647
1648 // test that the default clone() implementation works, and returns NULL
1649 if(ten.clone()!=NULL) {
1650 errln("StringEnumeration.clone()!=NULL");
1651 }
1652 }
1653
1654 void
TestCharString()1655 UnicodeStringTest::TestCharString() {
1656 static const char originalCStr[] =
1657 "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.";
1658 CharString chStr(originalCStr);
1659 if (strcmp(originalCStr, chStr) != 0) {
1660 errln("CharString doesn't work with large strings.");
1661 }
1662 }
1663
1664 /*
1665 * Namespace test, to make sure that macros like UNICODE_STRING include the
1666 * namespace qualifier.
1667 *
1668 * Define a (bogus) UnicodeString class in another namespace and check for ambiguity.
1669 */
1670 #if U_HAVE_NAMESPACE
1671 namespace bogus {
1672 class UnicodeString {
1673 public:
1674 enum EInvariant { kInvariant };
UnicodeString()1675 UnicodeString() : i(1) {}
UnicodeString(UBool,const UChar *,int32_t textLength)1676 UnicodeString(UBool /*isTerminated*/, const UChar * /*text*/, int32_t textLength) : i(textLength) {}
UnicodeString(const char *,int32_t length,enum EInvariant)1677 UnicodeString(const char * /*src*/, int32_t length, enum EInvariant /*inv*/
1678 ) : i(length) {}
1679 private:
1680 int32_t i;
1681 };
1682 }
1683 #endif
1684
1685 void
TestNameSpace()1686 UnicodeStringTest::TestNameSpace() {
1687 #if U_HAVE_NAMESPACE
1688 // Provoke name collision unless the UnicodeString macros properly
1689 // qualify the icu::UnicodeString class.
1690 using namespace bogus;
1691
1692 // Use all UnicodeString macros from unistr.h.
1693 icu::UnicodeString s1=icu::UnicodeString("abc", 3, US_INV);
1694 icu::UnicodeString s2=UNICODE_STRING("def", 3);
1695 icu::UnicodeString s3=UNICODE_STRING_SIMPLE("ghi");
1696
1697 // Make sure the compiler does not optimize away instantiation of s1, s2, s3.
1698 icu::UnicodeString s4=s1+s2+s3;
1699 if(s4.length()!=9) {
1700 errln("Something wrong with UnicodeString::operator+().");
1701 }
1702 #endif
1703 }
1704