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