]>
git.saurik.com Git - apple/icu.git/blob - icuSources/test/intltest/citrtest.cpp
1 /********************************************************************
3 * Copyright (c) 1997-2004, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 * Modification History:
7 * Date Name Description
8 * 05/22/2000 Madhu Added tests for testing new API for utf16 support and more
9 **********************************************************************/
12 #include "unicode/chariter.h"
13 #include "unicode/ustring.h"
14 #include "unicode/unistr.h"
15 #include "unicode/schriter.h"
16 #include "unicode/uchriter.h"
17 #include "unicode/uiter.h"
18 #include "unicode/putil.h"
22 class SCharacterIterator
: public CharacterIterator
{
24 SCharacterIterator(const UnicodeString
& textStr
){
27 textLength
= textStr
.length();
33 virtual ~SCharacterIterator(){};
36 void setText(const UnicodeString
& newText
){
40 virtual void getText(UnicodeString
& result
) {
41 text
.extract(0,text
.length(),result
);
43 virtual UClassID
getDynamicClassID(void) const{
44 return getStaticClassID();
47 static UClassID
getStaticClassID(void){
48 return (UClassID
)(&fgClassID
);
50 virtual UBool
operator==(const ForwardCharacterIterator
& /*that*/) const{
54 virtual CharacterIterator
* clone(void) const {
57 virtual int32_t hashCode(void) const{
60 virtual UChar
nextPostInc(void){ return text
.charAt(pos
++);}
61 virtual UChar32
next32PostInc(void){return text
.char32At(pos
++);}
62 virtual UBool
hasNext() { return TRUE
;};
63 virtual UChar
first(){return DONE
;};
64 virtual UChar32
first32(){return DONE
;};
65 virtual UChar
last(){return DONE
;};
66 virtual UChar32
last32(){return DONE
;};
67 virtual UChar
setIndex(int32_t /*pos*/){return DONE
;};
68 virtual UChar32
setIndex32(int32_t /*pos*/){return DONE
;};
69 virtual UChar
current() const{return DONE
;};
70 virtual UChar32
current32() const{return DONE
;};
71 virtual UChar
next(){return DONE
;};
72 virtual UChar32
next32(){return DONE
;};
73 virtual UChar
previous(){return DONE
;};
74 virtual UChar32
previous32(){return DONE
;};
75 virtual int32_t move(int32_t delta
,CharacterIterator::EOrigin origin
){
92 } else if(pos
> end
) {
98 virtual int32_t move32(int32_t delta
, CharacterIterator::EOrigin origin
){
103 UTF_FWD_N(text
, pos
, end
, delta
);
108 UTF_FWD_N(text
, pos
, end
, delta
);
110 UTF_BACK_N(text
, begin
, pos
, -delta
);
116 UTF_BACK_N(text
, begin
, pos
, -delta
);
125 virtual UBool
hasPrevious() {return TRUE
;};
127 SCharacterIterator
& operator=(const SCharacterIterator
& that
){
135 static const char fgClassID
;
137 const char SCharacterIterator::fgClassID
=0;
139 #define LENGTHOF(array) ((int32_t)(sizeof(array)/sizeof((array)[0])))
141 CharIterTest::CharIterTest()
144 void CharIterTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
146 if (exec
) logln("TestSuite LocaleTest: ");
148 case 0: name
= "TestConstructionAndEquality"; if (exec
) TestConstructionAndEquality(); break;
149 case 1: name
= "TestConstructionAndEqualityUChariter"; if (exec
) TestConstructionAndEqualityUChariter(); break;
150 case 2: name
= "TestIteration"; if (exec
) TestIteration(); break;
151 case 3: name
= "TestIterationUChar32"; if (exec
) TestIterationUChar32(); break;
152 case 4: name
= "TestUCharIterator"; if (exec
) TestUCharIterator(); break;
153 case 5: name
= "TestCoverage"; if(exec
) TestCoverage(); break;
154 case 6: name
= "TestCharIteratorSubClasses"; if (exec
) TestCharIteratorSubClasses(); break;
155 default: name
= ""; break; //needed to end loop
159 void CharIterTest::TestCoverage(){
160 UnicodeString
testText("Now is the time for all good men to come to the aid of their country.");
161 UnicodeString
testText2("\\ud800\\udc01deadbeef");
162 testText2
= testText2
.unescape();
163 SCharacterIterator
* test
= new SCharacterIterator(testText
);
164 if(test
->firstPostInc()!= 0x004E){
165 errln("Failed: firstPostInc() failed");
167 if(test
->getIndex()!=1){
168 errln("Failed: getIndex().");
170 if(test
->getLength()!=testText
.length()){
171 errln("Failed: getLength()");
174 if(test
->getIndex()!=0){
175 errln("Failed: setToStart().");
178 if(test
->getIndex()!=testText
.length()){
179 errln("Failed: setToEnd().");
181 if(test
->startIndex() != 0){
182 errln("Failed: startIndex()");
184 test
->setText(testText2
);
185 if(test
->first32PostInc()!= testText2
.char32At(0)){
186 errln("Failed: first32PostInc() failed");
192 void CharIterTest::TestConstructionAndEquality() {
193 UnicodeString
testText("Now is the time for all good men to come to the aid of their country.");
194 UnicodeString
testText2("Don't bother using this string.");
195 UnicodeString result1
, result2
, result3
;
197 CharacterIterator
* test1
= new StringCharacterIterator(testText
);
198 CharacterIterator
* test1b
= new StringCharacterIterator(testText
, -1);
199 CharacterIterator
* test1c
= new StringCharacterIterator(testText
, 100);
200 CharacterIterator
* test1d
= new StringCharacterIterator(testText
, -2, 100, 5);
201 CharacterIterator
* test1e
= new StringCharacterIterator(testText
, 100, 20, 5);
202 CharacterIterator
* test2
= new StringCharacterIterator(testText
, 5);
203 CharacterIterator
* test3
= new StringCharacterIterator(testText
, 2, 20, 5);
204 CharacterIterator
* test4
= new StringCharacterIterator(testText2
);
205 CharacterIterator
* test5
= test1
->clone();
207 if (test1d
->startIndex() < 0)
208 errln("Construction failed: startIndex is negative");
209 if (test1d
->endIndex() > testText
.length())
210 errln("Construction failed: endIndex is greater than the text length");
211 if (test1d
->getIndex() < test1d
->startIndex() || test1d
->endIndex() < test1d
->getIndex())
212 errln("Construction failed: index is invalid");
214 if (*test1
== *test2
|| *test1
== *test3
|| *test1
== *test4
)
215 errln("Construction or operator== failed: Unequal objects compared equal");
216 if (*test1
!= *test5
)
217 errln("clone() or equals() failed: Two clones tested unequal");
219 if (test1
->hashCode() == test2
->hashCode() || test1
->hashCode() == test3
->hashCode()
220 || test1
->hashCode() == test4
->hashCode())
221 errln("hashCode() failed: different objects have same hash code");
223 if (test1
->hashCode() != test5
->hashCode())
224 errln("hashCode() failed: identical objects have different hash codes");
226 if(test1
->getLength() != testText
.length()){
227 errln("getLength of CharacterIterator failed");
229 test1
->getText(result1
);
230 test1b
->getText(result2
);
231 test1c
->getText(result3
);
232 if(result1
!= result2
|| result1
!= result3
)
233 errln("construction failed or getText() failed");
237 if (*test1
!= *test2
|| *test1
== *test5
)
238 errln("setIndex() failed");
240 *((StringCharacterIterator
*)test1
) = *((StringCharacterIterator
*)test3
);
241 if (*test1
!= *test3
|| *test1
== *test5
)
242 errln("operator= failed");
254 StringCharacterIterator
* testChar1
=new StringCharacterIterator(testText
);
255 StringCharacterIterator
* testChar2
=new StringCharacterIterator(testText2
);
256 StringCharacterIterator
* testChar3
=(StringCharacterIterator
*)test1
->clone();
258 testChar1
->getText(result1
);
259 testChar2
->getText(result2
);
260 testChar3
->getText(result3
);
261 if(result1
!= result3
|| result1
== result2
)
262 errln("getText() failed");
263 testChar3
->setText(testText2
);
264 testChar3
->getText(result3
);
265 if(result1
== result3
|| result2
!= result3
)
266 errln("setText() or getText() failed");
267 testChar3
->setText(testText
);
268 testChar3
->getText(result3
);
269 if(result1
!= result3
|| result1
== result2
)
270 errln("setText() or getText() round-trip failed");
278 void CharIterTest::TestConstructionAndEqualityUChariter() {
279 U_STRING_DECL(testText
, "Now is the time for all good men to come to the aid of their country.", 69);
280 U_STRING_DECL(testText2
, "Don't bother using this string.", 31);
282 U_STRING_INIT(testText
, "Now is the time for all good men to come to the aid of their country.", 69);
283 U_STRING_INIT(testText2
, "Don't bother using this string.", 31);
285 UnicodeString result
, result4
, result5
;
287 UCharCharacterIterator
* test1
= new UCharCharacterIterator(testText
, u_strlen(testText
));
288 UCharCharacterIterator
* test2
= new UCharCharacterIterator(testText
, u_strlen(testText
), 5);
289 UCharCharacterIterator
* test3
= new UCharCharacterIterator(testText
, u_strlen(testText
), 2, 20, 5);
290 UCharCharacterIterator
* test4
= new UCharCharacterIterator(testText2
, u_strlen(testText2
));
291 UCharCharacterIterator
* test5
= (UCharCharacterIterator
*)test1
->clone();
292 UCharCharacterIterator
* test6
= new UCharCharacterIterator(*test1
);
294 // j785: length=-1 will use u_strlen()
295 UCharCharacterIterator
* test7a
= new UCharCharacterIterator(testText
, -1);
296 UCharCharacterIterator
* test7b
= new UCharCharacterIterator(testText
, -1);
297 UCharCharacterIterator
* test7c
= new UCharCharacterIterator(testText
, -1, 2, 20, 5);
300 UCharCharacterIterator
* test8a
= new UCharCharacterIterator(testText
, -1, -1, 20, 5);
301 UCharCharacterIterator
* test8b
= new UCharCharacterIterator(testText
, -1, 2, 100, 5);
302 UCharCharacterIterator
* test8c
= new UCharCharacterIterator(testText
, -1, 2, 20, 100);
304 if (test8a
->startIndex() < 0)
305 errln("Construction failed: startIndex is negative");
306 if (test8b
->endIndex() != u_strlen(testText
))
307 errln("Construction failed: endIndex is different from the text length");
308 if (test8c
->getIndex() < test8c
->startIndex() || test8c
->endIndex() < test8c
->getIndex())
309 errln("Construction failed: index is invalid");
311 if (*test1
== *test2
|| *test1
== *test3
|| *test1
== *test4
)
312 errln("Construction or operator== failed: Unequal objects compared equal");
313 if (*test1
!= *test5
)
314 errln("clone() or equals() failed: Two clones tested unequal");
316 if (*test6
!= *test1
)
317 errln("copy construction or equals() failed: Two copies tested unequal");
319 if (test1
->hashCode() == test2
->hashCode() || test1
->hashCode() == test3
->hashCode()
320 || test1
->hashCode() == test4
->hashCode())
321 errln("hashCode() failed: different objects have same hash code");
323 if (test1
->hashCode() != test5
->hashCode())
324 errln("hashCode() failed: identical objects have different hash codes");
326 test7a
->getText(result
);
327 test7b
->getText(result4
);
328 test7c
->getText(result5
);
330 if(result
!= UnicodeString(testText
) || result4
!= result
|| result5
!= result
)
331 errln("error in construction");
333 test1
->getText(result
);
334 test4
->getText(result4
);
335 test5
->getText(result5
);
336 if(result
!= result5
|| result
== result4
)
337 errln("getText() failed");
338 test5
->setText(testText2
, u_strlen(testText2
));
339 test5
->getText(result5
);
340 if(result
== result5
|| result4
!= result5
)
341 errln("setText() or getText() failed");
342 test5
->setText(testText
, u_strlen(testText
));
343 test5
->getText(result5
);
344 if(result
!= result5
|| result
== result4
)
345 errln("setText() or getText() round-trip failed");
349 if (*test1
!= *test2
|| *test1
== *test5
)
350 errln("setIndex() failed");
351 test8b
->setIndex32(5);
352 if (test8b
->getIndex()!=5)
353 errln("setIndex32() failed");
356 if (*test1
!= *test3
|| *test1
== *test5
)
357 errln("operator= failed");
374 void CharIterTest::TestIteration() {
375 UnicodeString
text("Now is the time for all good men to come to the aid of their country.");
380 StringCharacterIterator
iter(text
, 5);
382 UnicodeString iterText
;
383 iter
.getText(iterText
);
384 if (iterText
!= text
)
385 errln("iter.getText() failed");
387 if (iter
.current() != text
[(int32_t)5])
388 errln("Iterator didn't start out in the right place.");
393 if (iter
.startIndex() != 0 || iter
.endIndex() != text
.length())
394 errln("startIndex() or endIndex() failed");
396 logln("Testing forward iteration...");
398 if (c
== CharacterIterator::DONE
&& i
!= text
.length())
399 errln("Iterator reached end prematurely");
400 else if (c
!= text
[i
])
401 errln((UnicodeString
)"Character mismatch at position " + i
+
402 ", iterator has " + UCharToUnicodeString(c
) +
403 ", string has " + UCharToUnicodeString(text
[i
]));
405 if (iter
.current() != c
)
406 errln("current() isn't working right");
407 if (iter
.getIndex() != i
)
408 errln("getIndex() isn't working right");
410 if (c
!= CharacterIterator::DONE
) {
414 } while (c
!= CharacterIterator::DONE
);
416 if(c
!= CharacterIterator::DONE
)
417 errln("next() didn't return DONE at the end");
418 c
=iter
.setIndex(text
.length()+1);
419 if(c
!= CharacterIterator::DONE
)
420 errln("setIndex(len+1) didn't return DONE");
423 i
= text
.length() - 1;
425 logln("Testing backward iteration...");
427 if (c
== CharacterIterator::DONE
&& i
>= 0)
428 errln("Iterator reached end prematurely");
429 else if (c
!= text
[i
])
430 errln((UnicodeString
)"Character mismatch at position " + i
+
431 ", iterator has " + UCharToUnicodeString(c
) +
432 ", string has " + UCharToUnicodeString(text
[i
]));
434 if (iter
.current() != c
)
435 errln("current() isn't working right");
436 if (iter
.getIndex() != i
)
437 errln("getIndex() isn't working right");
438 if(iter
.setIndex(i
) != c
)
439 errln("setIndex() isn't working right");
441 if (c
!= CharacterIterator::DONE
) {
445 } while (c
!= CharacterIterator::DONE
);
448 if(c
!= CharacterIterator::DONE
)
449 errln("previous didn't return DONE at the beginning");
452 //testing firstPostInc, nextPostInc, setTostart
454 c
=iter
.firstPostInc();
456 errln((UnicodeString
)"firstPostInc failed. Expected->" +
457 UCharToUnicodeString(text
[i
]) + " Got->" + UCharToUnicodeString(c
));
458 if(iter
.getIndex() != i
+1)
459 errln((UnicodeString
)"getIndex() after firstPostInc() failed");
463 if (iter
.startIndex() != 0)
464 errln("setToStart failed");
466 logln("Testing forward iteration...");
468 if (c
!= CharacterIterator::DONE
)
469 c
= iter
.nextPostInc();
472 errln((UnicodeString
)"Character mismatch at position " + i
+
473 (UnicodeString
)", iterator has " + UCharToUnicodeString(c
) +
474 (UnicodeString
)", string has " + UCharToUnicodeString(text
[i
]));
477 if(iter
.getIndex() != i
)
478 errln("getIndex() aftr nextPostInc() isn't working right");
479 if(iter
.current() != text
[i
])
480 errln("current() after nextPostInc() isn't working right");
481 } while (iter
.hasNext());
482 c
=iter
.nextPostInc();
483 if(c
!= CharacterIterator::DONE
)
484 errln("nextPostInc() didn't return DONE at the beginning");
488 StringCharacterIterator
iter(text
, 5, 15, 10);
489 if (iter
.startIndex() != 5 || iter
.endIndex() != 15)
490 errln("creation of a restricted-range iterator failed");
492 if (iter
.getIndex() != 10 || iter
.current() != text
[(int32_t)10])
493 errln("starting the iterator in the middle didn't work");
498 logln("Testing forward iteration over a range...");
500 if (c
== CharacterIterator::DONE
&& i
!= 15)
501 errln("Iterator reached end prematurely");
502 else if (c
!= text
[i
])
503 errln((UnicodeString
)"Character mismatch at position " + i
+
504 ", iterator has " + UCharToUnicodeString(c
) +
505 ", string has " + UCharToUnicodeString(text
[i
]));
507 if (iter
.current() != c
)
508 errln("current() isn't working right");
509 if (iter
.getIndex() != i
)
510 errln("getIndex() isn't working right");
511 if(iter
.setIndex(i
) != c
)
512 errln("setIndex() isn't working right");
514 if (c
!= CharacterIterator::DONE
) {
518 } while (c
!= CharacterIterator::DONE
);
523 logln("Testing backward iteration over a range...");
525 if (c
== CharacterIterator::DONE
&& i
>= 5)
526 errln("Iterator reached end prematurely");
527 else if (c
!= text
[i
])
528 errln((UnicodeString
)"Character mismatch at position " + i
+
529 ", iterator has " + UCharToUnicodeString(c
) +
530 ", string has " + UCharToUnicodeString(text
[i
]));
532 if (iter
.current() != c
)
533 errln("current() isn't working right");
534 if (iter
.getIndex() != i
)
535 errln("getIndex() isn't working right");
537 if (c
!= CharacterIterator::DONE
) {
541 } while (c
!= CharacterIterator::DONE
);
547 //Tests for new API for utf-16 support
548 void CharIterTest::TestIterationUChar32() {
549 UChar textChars
[]={ 0x0061, 0x0062, 0xd841, 0xdc02, 0x20ac, 0xd7ff, 0xd842, 0xdc06, 0xd801, 0xdc00, 0x0061, 0x0000};
550 UnicodeString
text(textChars
);
554 StringCharacterIterator
iter(text
, 1);
556 UnicodeString iterText
;
557 iter
.getText(iterText
);
558 if (iterText
!= text
)
559 errln("iter.getText() failed");
561 if (iter
.current32() != text
[(int32_t)1])
562 errln("Iterator didn't start out in the right place.");
566 i
=iter
.move32(1, CharacterIterator::kStart
);
568 if(c
!= text
.char32At(1) || i
!=1)
569 errln("move32(1, kStart) didn't work correctly expected %X got %X", c
, text
.char32At(1) );
571 i
=iter
.move32(2, CharacterIterator::kCurrent
);
573 if(c
!= text
.char32At(4) || i
!=4)
574 errln("move32(2, kCurrent) didn't work correctly expected %X got %X i=%ld", c
, text
.char32At(4), i
);
576 i
=iter
.move32(-2, CharacterIterator::kCurrent
);
578 if(c
!= text
.char32At(1) || i
!=1)
579 errln("move32(-2, kCurrent) didn't work correctly expected %X got %X i=%d", c
, text
.char32At(1), i
);
582 i
=iter
.move32(-2, CharacterIterator::kEnd
);
584 if(c
!= text
.char32At((text
.length()-3)) || i
!=(text
.length()-3))
585 errln("move32(-2, kEnd) didn't work correctly expected %X got %X i=%d", c
, text
.char32At((text
.length()-3)), i
);
591 if (iter
.startIndex() != 0 || iter
.endIndex() != text
.length())
592 errln("startIndex() or endIndex() failed");
594 logln("Testing forward iteration...");
596 /* logln("c=%d i=%d char32At=%d", c, i, text.char32At(i)); */
597 if (c
== CharacterIterator::DONE
&& i
!= text
.length())
598 errln("Iterator reached end prematurely");
599 else if(iter
.hasNext() == FALSE
&& i
!= text
.length())
600 errln("Iterator reached end prematurely. Failed at hasNext");
601 else if (c
!= text
.char32At(i
))
602 errln("Character mismatch at position %d, iterator has %X, string has %X", i
, c
, text
.char32At(i
));
604 if (iter
.current32() != c
)
605 errln("current32() isn't working right");
606 if(iter
.setIndex32(i
) != c
)
607 errln("setIndex32() isn't working right");
608 if (c
!= CharacterIterator::DONE
) {
610 i
=UTF16_NEED_MULTIPLE_UCHAR(c
) ? i
+2 : i
+1;
612 } while (c
!= CharacterIterator::DONE
);
613 if(iter
.hasNext() == TRUE
)
614 errln("hasNext() returned true at the end of the string");
619 if(iter
.getIndex() != text
.length() || iter
.hasNext() != FALSE
)
620 errln("setToEnd failed");
623 if(c
!= CharacterIterator::DONE
)
624 errln("next32 didn't return DONE at the end");
625 c
=iter
.setIndex32(text
.length()+1);
626 if(c
!= CharacterIterator::DONE
)
627 errln("setIndex32(len+1) didn't return DONE");
632 logln("Testing backward iteration...");
634 if (c
== CharacterIterator::DONE
&& i
>= 0)
635 errln((UnicodeString
)"Iterator reached start prematurely for i=" + i
);
636 else if(iter
.hasPrevious() == FALSE
&& i
>0)
637 errln((UnicodeString
)"Iterator reached start prematurely for i=" + i
);
638 else if (c
!= text
.char32At(i
))
639 errln("Character mismatch at position %d, iterator has %X, string has %X", i
, c
, text
.char32At(i
));
641 if (iter
.current32() != c
)
642 errln("current32() isn't working right");
643 if(iter
.setIndex32(i
) != c
)
644 errln("setIndex32() isn't working right");
645 if (iter
.getIndex() != i
)
646 errln("getIndex() isn't working right");
647 if (c
!= CharacterIterator::DONE
) {
648 c
= iter
.previous32();
649 i
=UTF16_NEED_MULTIPLE_UCHAR(c
) ? i
-2 : i
-1;
651 } while (c
!= CharacterIterator::DONE
);
652 if(iter
.hasPrevious() == TRUE
)
653 errln("hasPrevious returned true after reaching the start");
656 if(c
!= CharacterIterator::DONE
)
657 errln("previous32 didn't return DONE at the beginning");
662 //testing first32PostInc, next32PostInc, setTostart
664 c
=iter
.first32PostInc();
665 if(c
!= text
.char32At(i
))
666 errln("first32PostInc failed. Expected->%X Got->%X", text
.char32At(i
), c
);
667 if(iter
.getIndex() != UTF16_CHAR_LENGTH(c
) + i
)
668 errln((UnicodeString
)"getIndex() after first32PostInc() failed");
672 if (iter
.startIndex() != 0)
673 errln("setToStart failed");
675 logln("Testing forward iteration...");
677 if (c
!= CharacterIterator::DONE
)
678 c
= iter
.next32PostInc();
680 if(c
!= text
.char32At(i
))
681 errln("Character mismatch at position %d, iterator has %X, string has %X", i
, c
, text
.char32At(i
));
683 i
=UTF16_NEED_MULTIPLE_UCHAR(c
) ? i
+2 : i
+1;
684 if(iter
.getIndex() != i
)
685 errln("getIndex() aftr next32PostInc() isn't working right");
686 if(iter
.current32() != text
.char32At(i
))
687 errln("current() after next32PostInc() isn't working right");
688 } while (iter
.hasNext());
689 c
=iter
.next32PostInc();
690 if(c
!= CharacterIterator::DONE
)
691 errln("next32PostInc() didn't return DONE at the beginning");
697 StringCharacterIterator
iter(text
, 1, 11, 10);
698 if (iter
.startIndex() != 1 || iter
.endIndex() != 11)
699 errln("creation of a restricted-range iterator failed");
701 if (iter
.getIndex() != 10 || iter
.current32() != text
.char32At(10))
702 errln("starting the iterator in the middle didn't work");
708 logln("Testing forward iteration over a range...");
710 if (c
== CharacterIterator::DONE
&& i
!= 11)
711 errln("Iterator reached end prematurely");
712 else if(iter
.hasNext() == FALSE
)
713 errln("Iterator reached end prematurely");
714 else if (c
!= text
.char32At(i
))
715 errln("Character mismatch at position %d, iterator has %X, string has %X", i
, c
, text
.char32At(i
));
717 if (iter
.current32() != c
)
718 errln("current32() isn't working right");
719 if(iter
.setIndex32(i
) != c
)
720 errln("setIndex32() isn't working right");
722 if (c
!= CharacterIterator::DONE
) {
724 i
=UTF16_NEED_MULTIPLE_UCHAR(c
) ? i
+2 : i
+1;
726 } while (c
!= CharacterIterator::DONE
);
728 if(c
!= CharacterIterator::DONE
)
729 errln("error in next32()");
735 logln("Testing backward iteration over a range...");
737 if (c
== CharacterIterator::DONE
&& i
>= 5)
738 errln("Iterator reached start prematurely");
739 else if(iter
.hasPrevious() == FALSE
&& i
> 5)
740 errln("Iterator reached start prematurely");
741 else if (c
!= text
.char32At(i
))
742 errln("Character mismatch at position %d, iterator has %X, string has %X", i
, c
, text
.char32At(i
));
743 if (iter
.current32() != c
)
744 errln("current32() isn't working right");
745 if (iter
.getIndex() != i
)
746 errln("getIndex() isn't working right");
747 if(iter
.setIndex32(i
) != c
)
748 errln("setIndex32() isn't working right");
750 if (c
!= CharacterIterator::DONE
) {
751 c
= iter
.previous32();
752 i
=UTF16_NEED_MULTIPLE_UCHAR(c
) ? i
-2 : i
-1;
755 } while (c
!= CharacterIterator::DONE
);
757 if(c
!= CharacterIterator::DONE
)
758 errln("error on previous32");
764 void CharIterTest::TestUCharIterator(UCharIterator
*iter
, CharacterIterator
&ci
,
765 const char *moves
, const char *which
) {
771 // move both iter and s[index]
774 h
=iter
->hasNext(iter
);
776 c
=iter
->current(iter
);
780 h
=iter
->hasNext(iter
);
782 c
=uiter_current32(iter
);
787 h
=iter
->hasNext(iter
);
793 h
=iter
->hasNext(iter
);
795 c
=uiter_next32(iter
);
796 c2
=ci
.next32PostInc();
800 h
=iter
->hasPrevious(iter
);
802 c
=iter
->previous(iter
);
806 h
=iter
->hasPrevious(iter
);
808 c
=uiter_previous32(iter
);
814 c
=(UChar32
)iter
->move(iter
, 2, UITER_CURRENT
);
815 c2
=(UChar32
)ci
.move(2, CharacterIterator::kCurrent
);
820 c
=(UChar32
)iter
->move(iter
, -2, UITER_CURRENT
);
821 c2
=(UChar32
)ci
.move(-2, CharacterIterator::kCurrent
);
827 errln("error: unexpected move character '%c' in \"%s\"", moves
[m
], moves
);
835 if(c
!=c2
|| h
!=h2
|| ci
.getIndex()!=iter
->getIndex(iter
, UITER_CURRENT
)) {
836 errln("error: UCharIterator(%s) misbehaving at \"%s\"[%d]='%c'", which
, moves
, m
, moves
[m
]);
841 void CharIterTest::TestUCharIterator() {
842 // test string of length 8
843 UnicodeString s
=UnicodeString("a \\U00010001b\\U0010fffdz", "").unescape();
844 const char *const moves
=
845 "0+++++++++" // 10 moves per line
851 StringCharacterIterator
sci(s
), compareCI(s
);
853 UCharIterator sIter
, cIter
, rIter
;
855 uiter_setString(&sIter
, s
.getBuffer(), s
.length());
856 uiter_setCharacterIterator(&cIter
, &sci
);
857 uiter_setReplaceable(&rIter
, &s
);
859 TestUCharIterator(&sIter
, compareCI
, moves
, "uiter_setString");
860 compareCI
.setIndex(0);
861 TestUCharIterator(&cIter
, compareCI
, moves
, "uiter_setCharacterIterator");
862 compareCI
.setIndex(0);
863 TestUCharIterator(&rIter
, compareCI
, moves
, "uiter_setReplaceable");
865 // test move & getIndex some more
869 if( sIter
.getIndex(&sIter
, UITER_ZERO
)!=0 ||
870 sIter
.getIndex(&sIter
, UITER_START
)!=2 ||
871 sIter
.getIndex(&sIter
, UITER_CURRENT
)!=3 ||
872 sIter
.getIndex(&sIter
, UITER_LIMIT
)!=5 ||
873 sIter
.getIndex(&sIter
, UITER_LENGTH
)!=s
.length()
875 errln("error: UCharIterator(string).getIndex returns wrong index");
878 if( sIter
.move(&sIter
, 4, UITER_ZERO
)!=4 ||
879 sIter
.move(&sIter
, 1, UITER_START
)!=3 ||
880 sIter
.move(&sIter
, 3, UITER_CURRENT
)!=5 ||
881 sIter
.move(&sIter
, -1, UITER_LIMIT
)!=4 ||
882 sIter
.move(&sIter
, -5, UITER_LENGTH
)!=3 ||
883 sIter
.move(&sIter
, 0, UITER_CURRENT
)!=sIter
.getIndex(&sIter
, UITER_CURRENT
) ||
884 sIter
.getIndex(&sIter
, UITER_CURRENT
)!=3
886 errln("error: UCharIterator(string).move sets/returns wrong index");
889 sci
=StringCharacterIterator(s
, 2, 5, 3);
890 uiter_setCharacterIterator(&cIter
, &sci
);
891 if( cIter
.getIndex(&cIter
, UITER_ZERO
)!=0 ||
892 cIter
.getIndex(&cIter
, UITER_START
)!=2 ||
893 cIter
.getIndex(&cIter
, UITER_CURRENT
)!=3 ||
894 cIter
.getIndex(&cIter
, UITER_LIMIT
)!=5 ||
895 cIter
.getIndex(&cIter
, UITER_LENGTH
)!=s
.length()
897 errln("error: UCharIterator(character iterator).getIndex returns wrong index");
900 if( cIter
.move(&cIter
, 4, UITER_ZERO
)!=4 ||
901 cIter
.move(&cIter
, 1, UITER_START
)!=3 ||
902 cIter
.move(&cIter
, 3, UITER_CURRENT
)!=5 ||
903 cIter
.move(&cIter
, -1, UITER_LIMIT
)!=4 ||
904 cIter
.move(&cIter
, -5, UITER_LENGTH
)!=3 ||
905 cIter
.move(&cIter
, 0, UITER_CURRENT
)!=cIter
.getIndex(&cIter
, UITER_CURRENT
) ||
906 cIter
.getIndex(&cIter
, UITER_CURRENT
)!=3
908 errln("error: UCharIterator(character iterator).move sets/returns wrong index");
912 if(cIter
.getIndex(&cIter
, (enum UCharIteratorOrigin
)-1) != -1)
914 errln("error: UCharIterator(char iter).getIndex did not return error value");
917 if(cIter
.move(&cIter
, 0, (enum UCharIteratorOrigin
)-1) != -1)
919 errln("error: UCharIterator(char iter).move did not return error value");
923 if(rIter
.getIndex(&rIter
, (enum UCharIteratorOrigin
)-1) != -1)
925 errln("error: UCharIterator(repl iter).getIndex did not return error value");
928 if(rIter
.move(&rIter
, 0, (enum UCharIteratorOrigin
)-1) != -1)
930 errln("error: UCharIterator(repl iter).move did not return error value");
934 if(sIter
.getIndex(&sIter
, (enum UCharIteratorOrigin
)-1) != -1)
936 errln("error: UCharIterator(string iter).getIndex did not return error value");
939 if(sIter
.move(&sIter
, 0, (enum UCharIteratorOrigin
)-1) != -1)
941 errln("error: UCharIterator(string iter).move did not return error value");
946 // subclass test, and completing API coverage -------------------------------
948 class SubCharIter
: public CharacterIterator
{
950 // public default constructor, to get coverage of CharacterIterator()
951 SubCharIter() : CharacterIterator() {
952 textLength
=end
=LENGTHOF(s
);
954 s
[1]=0xd900; // U+50400
959 // useful stuff, mostly dummy but testing coverage and subclassability
960 virtual UChar
nextPostInc() {
961 if(pos
<LENGTHOF(s
)) {
968 virtual UChar32
next32PostInc() {
969 if(pos
<LENGTHOF(s
)) {
971 U16_NEXT(s
, pos
, LENGTHOF(s
), c
);
978 virtual UBool
hasNext() {
979 return pos
<LENGTHOF(s
);
982 virtual UChar
first() {
987 virtual UChar32
first32() {
990 U16_NEXT(s
, pos
, LENGTHOF(s
), c
);
995 virtual UChar
setIndex(int32_t position
) {
996 if(0<=position
&& position
<=LENGTHOF(s
)) {
998 if(pos
<LENGTHOF(s
)) {
1005 virtual UChar32
setIndex32(int32_t position
) {
1006 if(0<=position
&& position
<=LENGTHOF(s
)) {
1008 if(pos
<LENGTHOF(s
)) {
1010 U16_GET(s
, 0, pos
, LENGTHOF(s
), c
);
1017 virtual UChar
current() const {
1018 if(pos
<LENGTHOF(s
)) {
1025 virtual UChar32
current32() const {
1026 if(pos
<LENGTHOF(s
)) {
1028 U16_GET(s
, 0, pos
, LENGTHOF(s
), c
);
1035 virtual UChar
next() {
1036 if(pos
<LENGTHOF(s
) && ++pos
<LENGTHOF(s
)) {
1043 virtual UChar32
next32() {
1044 if(pos
<LENGTHOF(s
)) {
1045 U16_FWD_1(s
, pos
, LENGTHOF(s
));
1047 if(pos
<LENGTHOF(s
)) {
1050 U16_NEXT(s
, i
, LENGTHOF(s
), c
);
1057 virtual UBool
hasPrevious() {
1061 virtual void getText(UnicodeString
&result
) {
1062 result
.setTo(s
, LENGTHOF(s
));
1065 // dummy implementations of other pure virtual base class functions
1066 virtual UBool
operator==(const ForwardCharacterIterator
&that
) const {
1069 getDynamicClassID()==that
.getDynamicClassID() && pos
==((SubCharIter
&)that
).pos
;
1072 virtual int32_t hashCode() const {
1076 virtual CharacterIterator
*clone() const {
1080 virtual UChar
last() {
1084 virtual UChar32
last32() {
1088 virtual UChar
previous() {
1092 virtual UChar32
previous32() {
1096 virtual int32_t move(int32_t /*delta*/, EOrigin
/*origin*/) {
1100 virtual int32_t move32(int32_t /*delta*/, EOrigin
/*origin*/) {
1105 virtual UClassID
getDynamicClassID() const {
1106 return getStaticClassID();
1109 static UClassID
getStaticClassID() {
1110 return (UClassID
)(&fgClassID
);
1114 // dummy string data
1117 static const char fgClassID
;
1120 const char SubCharIter::fgClassID
= 0;
1122 class SubStringCharIter
: public StringCharacterIterator
{
1124 SubStringCharIter() {
1125 setText(UNICODE_STRING("abc", 3));
1129 class SubUCharCharIter
: public UCharCharacterIterator
{
1131 SubUCharCharIter() {
1136 static const UChar u
[3];
1139 const UChar
SubUCharCharIter::u
[3]={ 0x61, 0x62, 0x63 };
1141 void CharIterTest::TestCharIteratorSubClasses() {
1144 // coverage - call functions that are not otherwise tested
1145 // first[32]PostInc() are default implementations that are overridden
1146 // in ICU's own CharacterIterator subclasses
1148 if(p
->firstPostInc()!=0x61) {
1149 errln("SubCharIter.firstPosInc() failed\n");
1153 p
=new SubCharIter
[2];
1154 if(p
[1].first32PostInc()!=0x61) {
1155 errln("SubCharIter.first32PosInc() failed\n");
1159 // coverage: StringCharacterIterator default constructor
1160 SubStringCharIter sci
;
1161 if(sci
.firstPostInc()!=0x61) {
1162 errln("SubStringCharIter.firstPostInc() failed\n");
1165 // coverage: UCharCharacterIterator default constructor
1166 SubUCharCharIter uci
;
1167 if(uci
.firstPostInc()!=0x61) {
1168 errln("SubUCharCharIter.firstPostInc() failed\n");