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