]>
git.saurik.com Git - apple/icu.git/blob - icuSources/test/intltest/citrtest.cpp
1 /****************************************************************************************
3 * Copyright (c) 1997-2012, 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 "utypeinfo.h" // for 'typeid' to work
14 #include "unicode/chariter.h"
15 #include "unicode/ustring.h"
16 #include "unicode/unistr.h"
17 #include "unicode/schriter.h"
18 #include "unicode/uchriter.h"
19 #include "unicode/uiter.h"
20 #include "unicode/putil.h"
21 #include "unicode/utf16.h"
25 class SCharacterIterator
: public CharacterIterator
{
27 SCharacterIterator(const UnicodeString
& textStr
){
30 textLength
= textStr
.length();
36 virtual ~SCharacterIterator(){};
39 void setText(const UnicodeString
& newText
){
43 virtual void getText(UnicodeString
& result
) {
44 text
.extract(0,text
.length(),result
);
46 static UClassID
getStaticClassID(void){
47 return (UClassID
)(&fgClassID
);
49 virtual UClassID
getDynamicClassID(void) const{
50 return getStaticClassID();
53 virtual UBool
operator==(const ForwardCharacterIterator
& /*that*/) const{
57 virtual CharacterIterator
* clone(void) const {
60 virtual int32_t hashCode(void) const{
63 virtual UChar
nextPostInc(void){ return text
.charAt(pos
++);}
64 virtual UChar32
next32PostInc(void){return text
.char32At(pos
++);}
65 virtual UBool
hasNext() { return TRUE
;};
66 virtual UChar
first(){return DONE
;};
67 virtual UChar32
first32(){return DONE
;};
68 virtual UChar
last(){return DONE
;};
69 virtual UChar32
last32(){return DONE
;};
70 virtual UChar
setIndex(int32_t /*pos*/){return DONE
;};
71 virtual UChar32
setIndex32(int32_t /*pos*/){return DONE
;};
72 virtual UChar
current() const{return DONE
;};
73 virtual UChar32
current32() const{return DONE
;};
74 virtual UChar
next(){return DONE
;};
75 virtual UChar32
next32(){return DONE
;};
76 virtual UChar
previous(){return DONE
;};
77 virtual UChar32
previous32(){return DONE
;};
78 virtual int32_t move(int32_t delta
,CharacterIterator::EOrigin origin
){
95 } else if(pos
> end
) {
101 virtual int32_t move32(int32_t delta
, CharacterIterator::EOrigin origin
){
106 U16_FWD_N(text
, pos
, end
, delta
);
111 U16_FWD_N(text
, pos
, end
, delta
);
113 U16_BACK_N(text
, begin
, pos
, -delta
);
119 U16_BACK_N(text
, begin
, pos
, -delta
);
128 virtual UBool
hasPrevious() {return TRUE
;};
130 SCharacterIterator
& operator=(const SCharacterIterator
& that
){
138 static const char fgClassID
;
140 const char SCharacterIterator::fgClassID
=0;
142 #define LENGTHOF(array) ((int32_t)(sizeof(array)/sizeof((array)[0])))
144 CharIterTest::CharIterTest()
147 void CharIterTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
149 if (exec
) logln("TestSuite CharIterTest: ");
151 case 0: name
= "TestConstructionAndEquality"; if (exec
) TestConstructionAndEquality(); break;
152 case 1: name
= "TestConstructionAndEqualityUChariter"; if (exec
) TestConstructionAndEqualityUChariter(); break;
153 case 2: name
= "TestIteration"; if (exec
) TestIteration(); break;
154 case 3: name
= "TestIterationUChar32"; if (exec
) TestIterationUChar32(); break;
155 case 4: name
= "TestUCharIterator"; if (exec
) TestUCharIterator(); break;
156 case 5: name
= "TestCoverage"; if(exec
) TestCoverage(); break;
157 case 6: name
= "TestCharIteratorSubClasses"; if (exec
) TestCharIteratorSubClasses(); break;
158 default: name
= ""; break; //needed to end loop
162 void CharIterTest::TestCoverage(){
163 UnicodeString
testText("Now is the time for all good men to come to the aid of their country.");
164 UnicodeString
testText2("\\ud800\\udc01deadbeef");
165 testText2
= testText2
.unescape();
166 SCharacterIterator
* test
= new SCharacterIterator(testText
);
167 if(test
->firstPostInc()!= 0x004E){
168 errln("Failed: firstPostInc() failed");
170 if(test
->getIndex()!=1){
171 errln("Failed: getIndex().");
173 if(test
->getLength()!=testText
.length()){
174 errln("Failed: getLength()");
177 if(test
->getIndex()!=0){
178 errln("Failed: setToStart().");
181 if(test
->getIndex()!=testText
.length()){
182 errln("Failed: setToEnd().");
184 if(test
->startIndex() != 0){
185 errln("Failed: startIndex()");
187 test
->setText(testText2
);
188 if(test
->first32PostInc()!= testText2
.char32At(0)){
189 errln("Failed: first32PostInc() failed");
195 void CharIterTest::TestConstructionAndEquality() {
196 UnicodeString
testText("Now is the time for all good men to come to the aid of their country.");
197 UnicodeString
testText2("Don't bother using this string.");
198 UnicodeString result1
, result2
, result3
;
200 CharacterIterator
* test1
= new StringCharacterIterator(testText
);
201 CharacterIterator
* test1b
= new StringCharacterIterator(testText
, -1);
202 CharacterIterator
* test1c
= new StringCharacterIterator(testText
, 100);
203 CharacterIterator
* test1d
= new StringCharacterIterator(testText
, -2, 100, 5);
204 CharacterIterator
* test1e
= new StringCharacterIterator(testText
, 100, 20, 5);
205 CharacterIterator
* test2
= new StringCharacterIterator(testText
, 5);
206 CharacterIterator
* test3
= new StringCharacterIterator(testText
, 2, 20, 5);
207 CharacterIterator
* test4
= new StringCharacterIterator(testText2
);
208 CharacterIterator
* test5
= test1
->clone();
210 if (test1d
->startIndex() < 0)
211 errln("Construction failed: startIndex is negative");
212 if (test1d
->endIndex() > testText
.length())
213 errln("Construction failed: endIndex is greater than the text length");
214 if (test1d
->getIndex() < test1d
->startIndex() || test1d
->endIndex() < test1d
->getIndex())
215 errln("Construction failed: index is invalid");
217 if (*test1
== *test2
|| *test1
== *test3
|| *test1
== *test4
)
218 errln("Construction or operator== failed: Unequal objects compared equal");
219 if (*test1
!= *test5
)
220 errln("clone() or equals() failed: Two clones tested unequal");
222 if (test1
->hashCode() == test2
->hashCode() || test1
->hashCode() == test3
->hashCode()
223 || test1
->hashCode() == test4
->hashCode())
224 errln("hashCode() failed: different objects have same hash code");
226 if (test1
->hashCode() != test5
->hashCode())
227 errln("hashCode() failed: identical objects have different hash codes");
229 if(test1
->getLength() != testText
.length()){
230 errln("getLength of CharacterIterator failed");
232 test1
->getText(result1
);
233 test1b
->getText(result2
);
234 test1c
->getText(result3
);
235 if(result1
!= result2
|| result1
!= result3
)
236 errln("construction failed or getText() failed");
240 if (*test1
!= *test2
|| *test1
== *test5
)
241 errln("setIndex() failed");
243 *((StringCharacterIterator
*)test1
) = *((StringCharacterIterator
*)test3
);
244 if (*test1
!= *test3
|| *test1
== *test5
)
245 errln("operator= failed");
257 StringCharacterIterator
* testChar1
=new StringCharacterIterator(testText
);
258 StringCharacterIterator
* testChar2
=new StringCharacterIterator(testText2
);
259 StringCharacterIterator
* testChar3
=(StringCharacterIterator
*)test1
->clone();
261 testChar1
->getText(result1
);
262 testChar2
->getText(result2
);
263 testChar3
->getText(result3
);
264 if(result1
!= result3
|| result1
== result2
)
265 errln("getText() failed");
266 testChar3
->setText(testText2
);
267 testChar3
->getText(result3
);
268 if(result1
== result3
|| result2
!= result3
)
269 errln("setText() or getText() failed");
270 testChar3
->setText(testText
);
271 testChar3
->getText(result3
);
272 if(result1
!= result3
|| result1
== result2
)
273 errln("setText() or getText() round-trip failed");
281 void CharIterTest::TestConstructionAndEqualityUChariter() {
282 U_STRING_DECL(testText
, "Now is the time for all good men to come to the aid of their country.", 69);
283 U_STRING_DECL(testText2
, "Don't bother using this string.", 31);
285 U_STRING_INIT(testText
, "Now is the time for all good men to come to the aid of their country.", 69);
286 U_STRING_INIT(testText2
, "Don't bother using this string.", 31);
288 UnicodeString result
, result4
, result5
;
290 UCharCharacterIterator
* test1
= new UCharCharacterIterator(testText
, u_strlen(testText
));
291 UCharCharacterIterator
* test2
= new UCharCharacterIterator(testText
, u_strlen(testText
), 5);
292 UCharCharacterIterator
* test3
= new UCharCharacterIterator(testText
, u_strlen(testText
), 2, 20, 5);
293 UCharCharacterIterator
* test4
= new UCharCharacterIterator(testText2
, u_strlen(testText2
));
294 UCharCharacterIterator
* test5
= (UCharCharacterIterator
*)test1
->clone();
295 UCharCharacterIterator
* test6
= new UCharCharacterIterator(*test1
);
297 // j785: length=-1 will use u_strlen()
298 UCharCharacterIterator
* test7a
= new UCharCharacterIterator(testText
, -1);
299 UCharCharacterIterator
* test7b
= new UCharCharacterIterator(testText
, -1);
300 UCharCharacterIterator
* test7c
= new UCharCharacterIterator(testText
, -1, 2, 20, 5);
303 UCharCharacterIterator
* test8a
= new UCharCharacterIterator(testText
, -1, -1, 20, 5);
304 UCharCharacterIterator
* test8b
= new UCharCharacterIterator(testText
, -1, 2, 100, 5);
305 UCharCharacterIterator
* test8c
= new UCharCharacterIterator(testText
, -1, 2, 20, 100);
307 if (test8a
->startIndex() < 0)
308 errln("Construction failed: startIndex is negative");
309 if (test8b
->endIndex() != u_strlen(testText
))
310 errln("Construction failed: endIndex is different from the text length");
311 if (test8c
->getIndex() < test8c
->startIndex() || test8c
->endIndex() < test8c
->getIndex())
312 errln("Construction failed: index is invalid");
314 if (*test1
== *test2
|| *test1
== *test3
|| *test1
== *test4
)
315 errln("Construction or operator== failed: Unequal objects compared equal");
316 if (*test1
!= *test5
)
317 errln("clone() or equals() failed: Two clones tested unequal");
319 if (*test6
!= *test1
)
320 errln("copy construction or equals() failed: Two copies tested unequal");
322 if (test1
->hashCode() == test2
->hashCode() || test1
->hashCode() == test3
->hashCode()
323 || test1
->hashCode() == test4
->hashCode())
324 errln("hashCode() failed: different objects have same hash code");
326 if (test1
->hashCode() != test5
->hashCode())
327 errln("hashCode() failed: identical objects have different hash codes");
329 test7a
->getText(result
);
330 test7b
->getText(result4
);
331 test7c
->getText(result5
);
333 if(result
!= UnicodeString(testText
) || result4
!= result
|| result5
!= result
)
334 errln("error in construction");
336 test1
->getText(result
);
337 test4
->getText(result4
);
338 test5
->getText(result5
);
339 if(result
!= result5
|| result
== result4
)
340 errln("getText() failed");
341 test5
->setText(testText2
, u_strlen(testText2
));
342 test5
->getText(result5
);
343 if(result
== result5
|| result4
!= result5
)
344 errln("setText() or getText() failed");
345 test5
->setText(testText
, u_strlen(testText
));
346 test5
->getText(result5
);
347 if(result
!= result5
|| result
== result4
)
348 errln("setText() or getText() round-trip failed");
352 if (*test1
!= *test2
|| *test1
== *test5
)
353 errln("setIndex() failed");
354 test8b
->setIndex32(5);
355 if (test8b
->getIndex()!=5)
356 errln("setIndex32() failed");
359 if (*test1
!= *test3
|| *test1
== *test5
)
360 errln("operator= failed");
377 void CharIterTest::TestIteration() {
378 UnicodeString
text("Now is the time for all good men to come to the aid of their country.");
383 StringCharacterIterator
iter(text
, 5);
385 UnicodeString iterText
;
386 iter
.getText(iterText
);
387 if (iterText
!= text
)
388 errln("iter.getText() failed");
390 if (iter
.current() != text
[(int32_t)5])
391 errln("Iterator didn't start out in the right place.");
396 if (iter
.startIndex() != 0 || iter
.endIndex() != text
.length())
397 errln("startIndex() or endIndex() failed");
399 logln("Testing forward iteration...");
401 if (c
== CharacterIterator::DONE
&& i
!= text
.length())
402 errln("Iterator reached end prematurely");
403 else if (c
!= text
[i
])
404 errln((UnicodeString
)"Character mismatch at position " + i
+
405 ", iterator has " + UCharToUnicodeString(c
) +
406 ", string has " + UCharToUnicodeString(text
[i
]));
408 if (iter
.current() != c
)
409 errln("current() isn't working right");
410 if (iter
.getIndex() != i
)
411 errln("getIndex() isn't working right");
413 if (c
!= CharacterIterator::DONE
) {
417 } while (c
!= CharacterIterator::DONE
);
419 if(c
!= CharacterIterator::DONE
)
420 errln("next() didn't return DONE at the end");
421 c
=iter
.setIndex(text
.length()+1);
422 if(c
!= CharacterIterator::DONE
)
423 errln("setIndex(len+1) didn't return DONE");
426 i
= text
.length() - 1;
428 logln("Testing backward iteration...");
430 if (c
== CharacterIterator::DONE
&& i
>= 0)
431 errln("Iterator reached end prematurely");
432 else if (c
!= text
[i
])
433 errln((UnicodeString
)"Character mismatch at position " + i
+
434 ", iterator has " + UCharToUnicodeString(c
) +
435 ", string has " + UCharToUnicodeString(text
[i
]));
437 if (iter
.current() != c
)
438 errln("current() isn't working right");
439 if (iter
.getIndex() != i
)
440 errln("getIndex() isn't working right");
441 if(iter
.setIndex(i
) != c
)
442 errln("setIndex() isn't working right");
444 if (c
!= CharacterIterator::DONE
) {
448 } while (c
!= CharacterIterator::DONE
);
451 if(c
!= CharacterIterator::DONE
)
452 errln("previous didn't return DONE at the beginning");
455 //testing firstPostInc, nextPostInc, setTostart
457 c
=iter
.firstPostInc();
459 errln((UnicodeString
)"firstPostInc failed. Expected->" +
460 UCharToUnicodeString(text
[i
]) + " Got->" + UCharToUnicodeString(c
));
461 if(iter
.getIndex() != i
+1)
462 errln((UnicodeString
)"getIndex() after firstPostInc() failed");
466 if (iter
.startIndex() != 0)
467 errln("setToStart failed");
469 logln("Testing forward iteration...");
471 if (c
!= CharacterIterator::DONE
)
472 c
= iter
.nextPostInc();
475 errln((UnicodeString
)"Character mismatch at position " + i
+
476 (UnicodeString
)", iterator has " + UCharToUnicodeString(c
) +
477 (UnicodeString
)", string has " + UCharToUnicodeString(text
[i
]));
480 if(iter
.getIndex() != i
)
481 errln("getIndex() aftr nextPostInc() isn't working right");
482 if(iter
.current() != text
[i
])
483 errln("current() after nextPostInc() isn't working right");
484 } while (iter
.hasNext());
485 c
=iter
.nextPostInc();
486 if(c
!= CharacterIterator::DONE
)
487 errln("nextPostInc() didn't return DONE at the beginning");
491 StringCharacterIterator
iter(text
, 5, 15, 10);
492 if (iter
.startIndex() != 5 || iter
.endIndex() != 15)
493 errln("creation of a restricted-range iterator failed");
495 if (iter
.getIndex() != 10 || iter
.current() != text
[(int32_t)10])
496 errln("starting the iterator in the middle didn't work");
501 logln("Testing forward iteration over a range...");
503 if (c
== CharacterIterator::DONE
&& i
!= 15)
504 errln("Iterator reached end prematurely");
505 else if (c
!= text
[i
])
506 errln((UnicodeString
)"Character mismatch at position " + i
+
507 ", iterator has " + UCharToUnicodeString(c
) +
508 ", string has " + UCharToUnicodeString(text
[i
]));
510 if (iter
.current() != c
)
511 errln("current() isn't working right");
512 if (iter
.getIndex() != i
)
513 errln("getIndex() isn't working right");
514 if(iter
.setIndex(i
) != c
)
515 errln("setIndex() isn't working right");
517 if (c
!= CharacterIterator::DONE
) {
521 } while (c
!= CharacterIterator::DONE
);
526 logln("Testing backward iteration over a range...");
528 if (c
== CharacterIterator::DONE
&& i
>= 5)
529 errln("Iterator reached end prematurely");
530 else if (c
!= text
[i
])
531 errln((UnicodeString
)"Character mismatch at position " + i
+
532 ", iterator has " + UCharToUnicodeString(c
) +
533 ", string has " + UCharToUnicodeString(text
[i
]));
535 if (iter
.current() != c
)
536 errln("current() isn't working right");
537 if (iter
.getIndex() != i
)
538 errln("getIndex() isn't working right");
540 if (c
!= CharacterIterator::DONE
) {
544 } while (c
!= CharacterIterator::DONE
);
550 //Tests for new API for utf-16 support
551 void CharIterTest::TestIterationUChar32() {
552 UChar textChars
[]={ 0x0061, 0x0062, 0xd841, 0xdc02, 0x20ac, 0xd7ff, 0xd842, 0xdc06, 0xd801, 0xdc00, 0x0061, 0x0000};
553 UnicodeString
text(textChars
);
557 StringCharacterIterator
iter(text
, 1);
559 UnicodeString iterText
;
560 iter
.getText(iterText
);
561 if (iterText
!= text
)
562 errln("iter.getText() failed");
564 if (iter
.current32() != text
[(int32_t)1])
565 errln("Iterator didn't start out in the right place.");
569 i
=iter
.move32(1, CharacterIterator::kStart
);
571 if(c
!= text
.char32At(1) || i
!=1)
572 errln("move32(1, kStart) didn't work correctly expected %X got %X", c
, text
.char32At(1) );
574 i
=iter
.move32(2, CharacterIterator::kCurrent
);
576 if(c
!= text
.char32At(4) || i
!=4)
577 errln("move32(2, kCurrent) didn't work correctly expected %X got %X i=%ld", c
, text
.char32At(4), i
);
579 i
=iter
.move32(-2, CharacterIterator::kCurrent
);
581 if(c
!= text
.char32At(1) || i
!=1)
582 errln("move32(-2, kCurrent) didn't work correctly expected %X got %X i=%d", c
, text
.char32At(1), i
);
585 i
=iter
.move32(-2, CharacterIterator::kEnd
);
587 if(c
!= text
.char32At((text
.length()-3)) || i
!=(text
.length()-3))
588 errln("move32(-2, kEnd) didn't work correctly expected %X got %X i=%d", c
, text
.char32At((text
.length()-3)), i
);
594 if (iter
.startIndex() != 0 || iter
.endIndex() != text
.length())
595 errln("startIndex() or endIndex() failed");
597 logln("Testing forward iteration...");
599 /* logln("c=%d i=%d char32At=%d", c, i, text.char32At(i)); */
600 if (c
== CharacterIterator::DONE
&& i
!= text
.length())
601 errln("Iterator reached end prematurely");
602 else if(iter
.hasNext() == FALSE
&& i
!= text
.length())
603 errln("Iterator reached end prematurely. Failed at hasNext");
604 else if (c
!= text
.char32At(i
))
605 errln("Character mismatch at position %d, iterator has %X, string has %X", i
, c
, text
.char32At(i
));
607 if (iter
.current32() != c
)
608 errln("current32() isn't working right");
609 if(iter
.setIndex32(i
) != c
)
610 errln("setIndex32() isn't working right");
611 if (c
!= CharacterIterator::DONE
) {
613 i
=UTF16_NEED_MULTIPLE_UCHAR(c
) ? i
+2 : i
+1;
615 } while (c
!= CharacterIterator::DONE
);
616 if(iter
.hasNext() == TRUE
)
617 errln("hasNext() returned true at the end of the string");
622 if(iter
.getIndex() != text
.length() || iter
.hasNext() != FALSE
)
623 errln("setToEnd failed");
626 if(c
!= CharacterIterator::DONE
)
627 errln("next32 didn't return DONE at the end");
628 c
=iter
.setIndex32(text
.length()+1);
629 if(c
!= CharacterIterator::DONE
)
630 errln("setIndex32(len+1) didn't return DONE");
635 logln("Testing backward iteration...");
637 if (c
== CharacterIterator::DONE
&& i
>= 0)
638 errln((UnicodeString
)"Iterator reached start prematurely for i=" + i
);
639 else if(iter
.hasPrevious() == FALSE
&& i
>0)
640 errln((UnicodeString
)"Iterator reached start prematurely for i=" + i
);
641 else if (c
!= text
.char32At(i
))
642 errln("Character mismatch at position %d, iterator has %X, string has %X", i
, c
, text
.char32At(i
));
644 if (iter
.current32() != c
)
645 errln("current32() isn't working right");
646 if(iter
.setIndex32(i
) != c
)
647 errln("setIndex32() isn't working right");
648 if (iter
.getIndex() != i
)
649 errln("getIndex() isn't working right");
650 if (c
!= CharacterIterator::DONE
) {
651 c
= iter
.previous32();
652 i
=UTF16_NEED_MULTIPLE_UCHAR(c
) ? i
-2 : i
-1;
654 } while (c
!= CharacterIterator::DONE
);
655 if(iter
.hasPrevious() == TRUE
)
656 errln("hasPrevious returned true after reaching the start");
659 if(c
!= CharacterIterator::DONE
)
660 errln("previous32 didn't return DONE at the beginning");
665 //testing first32PostInc, next32PostInc, setTostart
667 c
=iter
.first32PostInc();
668 if(c
!= text
.char32At(i
))
669 errln("first32PostInc failed. Expected->%X Got->%X", text
.char32At(i
), c
);
670 if(iter
.getIndex() != U16_LENGTH(c
) + i
)
671 errln((UnicodeString
)"getIndex() after first32PostInc() failed");
675 if (iter
.startIndex() != 0)
676 errln("setToStart failed");
678 logln("Testing forward iteration...");
680 if (c
!= CharacterIterator::DONE
)
681 c
= iter
.next32PostInc();
683 if(c
!= text
.char32At(i
))
684 errln("Character mismatch at position %d, iterator has %X, string has %X", i
, c
, text
.char32At(i
));
686 i
=UTF16_NEED_MULTIPLE_UCHAR(c
) ? i
+2 : i
+1;
687 if(iter
.getIndex() != i
)
688 errln("getIndex() aftr next32PostInc() isn't working right");
689 if(iter
.current32() != text
.char32At(i
))
690 errln("current() after next32PostInc() isn't working right");
691 } while (iter
.hasNext());
692 c
=iter
.next32PostInc();
693 if(c
!= CharacterIterator::DONE
)
694 errln("next32PostInc() didn't return DONE at the beginning");
700 StringCharacterIterator
iter(text
, 1, 11, 10);
701 if (iter
.startIndex() != 1 || iter
.endIndex() != 11)
702 errln("creation of a restricted-range iterator failed");
704 if (iter
.getIndex() != 10 || iter
.current32() != text
.char32At(10))
705 errln("starting the iterator in the middle didn't work");
711 logln("Testing forward iteration over a range...");
713 if (c
== CharacterIterator::DONE
&& i
!= 11)
714 errln("Iterator reached end prematurely");
715 else if(iter
.hasNext() == FALSE
)
716 errln("Iterator reached end prematurely");
717 else if (c
!= text
.char32At(i
))
718 errln("Character mismatch at position %d, iterator has %X, string has %X", i
, c
, text
.char32At(i
));
720 if (iter
.current32() != c
)
721 errln("current32() isn't working right");
722 if(iter
.setIndex32(i
) != c
)
723 errln("setIndex32() isn't working right");
725 if (c
!= CharacterIterator::DONE
) {
727 i
=UTF16_NEED_MULTIPLE_UCHAR(c
) ? i
+2 : i
+1;
729 } while (c
!= CharacterIterator::DONE
);
731 if(c
!= CharacterIterator::DONE
)
732 errln("error in next32()");
738 logln("Testing backward iteration over a range...");
740 if (c
== CharacterIterator::DONE
&& i
>= 5)
741 errln("Iterator reached start prematurely");
742 else if(iter
.hasPrevious() == FALSE
&& i
> 5)
743 errln("Iterator reached start prematurely");
744 else if (c
!= text
.char32At(i
))
745 errln("Character mismatch at position %d, iterator has %X, string has %X", i
, c
, text
.char32At(i
));
746 if (iter
.current32() != c
)
747 errln("current32() isn't working right");
748 if (iter
.getIndex() != i
)
749 errln("getIndex() isn't working right");
750 if(iter
.setIndex32(i
) != c
)
751 errln("setIndex32() isn't working right");
753 if (c
!= CharacterIterator::DONE
) {
754 c
= iter
.previous32();
755 i
=UTF16_NEED_MULTIPLE_UCHAR(c
) ? i
-2 : i
-1;
758 } while (c
!= CharacterIterator::DONE
);
760 if(c
!= CharacterIterator::DONE
)
761 errln("error on previous32");
767 void CharIterTest::TestUCharIterator(UCharIterator
*iter
, CharacterIterator
&ci
,
768 const char *moves
, const char *which
) {
774 // move both iter and s[index]
777 h
=iter
->hasNext(iter
);
779 c
=iter
->current(iter
);
783 h
=iter
->hasNext(iter
);
785 c
=uiter_current32(iter
);
790 h
=iter
->hasNext(iter
);
796 h
=iter
->hasNext(iter
);
798 c
=uiter_next32(iter
);
799 c2
=ci
.next32PostInc();
803 h
=iter
->hasPrevious(iter
);
805 c
=iter
->previous(iter
);
809 h
=iter
->hasPrevious(iter
);
811 c
=uiter_previous32(iter
);
817 c
=(UChar32
)iter
->move(iter
, 2, UITER_CURRENT
);
818 c2
=(UChar32
)ci
.move(2, CharacterIterator::kCurrent
);
823 c
=(UChar32
)iter
->move(iter
, -2, UITER_CURRENT
);
824 c2
=(UChar32
)ci
.move(-2, CharacterIterator::kCurrent
);
830 errln("error: unexpected move character '%c' in \"%s\"", moves
[m
], moves
);
838 if(c
!=c2
|| h
!=h2
|| ci
.getIndex()!=iter
->getIndex(iter
, UITER_CURRENT
)) {
839 errln("error: UCharIterator(%s) misbehaving at \"%s\"[%d]='%c'", which
, moves
, m
, moves
[m
]);
844 void CharIterTest::TestUCharIterator() {
845 // test string of length 8
846 UnicodeString s
=UnicodeString("a \\U00010001b\\U0010fffdz", "").unescape();
847 const char *const moves
=
848 "0+++++++++" // 10 moves per line
854 StringCharacterIterator
sci(s
), compareCI(s
);
856 UCharIterator sIter
, cIter
, rIter
;
858 uiter_setString(&sIter
, s
.getBuffer(), s
.length());
859 uiter_setCharacterIterator(&cIter
, &sci
);
860 uiter_setReplaceable(&rIter
, &s
);
862 TestUCharIterator(&sIter
, compareCI
, moves
, "uiter_setString");
863 compareCI
.setIndex(0);
864 TestUCharIterator(&cIter
, compareCI
, moves
, "uiter_setCharacterIterator");
865 compareCI
.setIndex(0);
866 TestUCharIterator(&rIter
, compareCI
, moves
, "uiter_setReplaceable");
868 // test move & getIndex some more
872 if( sIter
.getIndex(&sIter
, UITER_ZERO
)!=0 ||
873 sIter
.getIndex(&sIter
, UITER_START
)!=2 ||
874 sIter
.getIndex(&sIter
, UITER_CURRENT
)!=3 ||
875 sIter
.getIndex(&sIter
, UITER_LIMIT
)!=5 ||
876 sIter
.getIndex(&sIter
, UITER_LENGTH
)!=s
.length()
878 errln("error: UCharIterator(string).getIndex returns wrong index");
881 if( sIter
.move(&sIter
, 4, UITER_ZERO
)!=4 ||
882 sIter
.move(&sIter
, 1, UITER_START
)!=3 ||
883 sIter
.move(&sIter
, 3, UITER_CURRENT
)!=5 ||
884 sIter
.move(&sIter
, -1, UITER_LIMIT
)!=4 ||
885 sIter
.move(&sIter
, -5, UITER_LENGTH
)!=3 ||
886 sIter
.move(&sIter
, 0, UITER_CURRENT
)!=sIter
.getIndex(&sIter
, UITER_CURRENT
) ||
887 sIter
.getIndex(&sIter
, UITER_CURRENT
)!=3
889 errln("error: UCharIterator(string).move sets/returns wrong index");
892 sci
=StringCharacterIterator(s
, 2, 5, 3);
893 uiter_setCharacterIterator(&cIter
, &sci
);
894 if( cIter
.getIndex(&cIter
, UITER_ZERO
)!=0 ||
895 cIter
.getIndex(&cIter
, UITER_START
)!=2 ||
896 cIter
.getIndex(&cIter
, UITER_CURRENT
)!=3 ||
897 cIter
.getIndex(&cIter
, UITER_LIMIT
)!=5 ||
898 cIter
.getIndex(&cIter
, UITER_LENGTH
)!=s
.length()
900 errln("error: UCharIterator(character iterator).getIndex returns wrong index");
903 if( cIter
.move(&cIter
, 4, UITER_ZERO
)!=4 ||
904 cIter
.move(&cIter
, 1, UITER_START
)!=3 ||
905 cIter
.move(&cIter
, 3, UITER_CURRENT
)!=5 ||
906 cIter
.move(&cIter
, -1, UITER_LIMIT
)!=4 ||
907 cIter
.move(&cIter
, -5, UITER_LENGTH
)!=3 ||
908 cIter
.move(&cIter
, 0, UITER_CURRENT
)!=cIter
.getIndex(&cIter
, UITER_CURRENT
) ||
909 cIter
.getIndex(&cIter
, UITER_CURRENT
)!=3
911 errln("error: UCharIterator(character iterator).move sets/returns wrong index");
915 if(cIter
.getIndex(&cIter
, (enum UCharIteratorOrigin
)-1) != -1)
917 errln("error: UCharIterator(char iter).getIndex did not return error value");
920 if(cIter
.move(&cIter
, 0, (enum UCharIteratorOrigin
)-1) != -1)
922 errln("error: UCharIterator(char iter).move did not return error value");
926 if(rIter
.getIndex(&rIter
, (enum UCharIteratorOrigin
)-1) != -1)
928 errln("error: UCharIterator(repl iter).getIndex did not return error value");
931 if(rIter
.move(&rIter
, 0, (enum UCharIteratorOrigin
)-1) != -1)
933 errln("error: UCharIterator(repl iter).move did not return error value");
937 if(sIter
.getIndex(&sIter
, (enum UCharIteratorOrigin
)-1) != -1)
939 errln("error: UCharIterator(string iter).getIndex did not return error value");
942 if(sIter
.move(&sIter
, 0, (enum UCharIteratorOrigin
)-1) != -1)
944 errln("error: UCharIterator(string iter).move did not return error value");
947 /* Testing function coverage on bad input */
948 UErrorCode status
= U_ZERO_ERROR
;
949 uiter_setString(&sIter
, NULL
, 1);
950 uiter_setState(&sIter
, 1, &status
);
951 if (status
!= U_UNSUPPORTED_ERROR
) {
952 errln("error: uiter_setState returned %s instead of U_UNSUPPORTED_ERROR", u_errorName(status
));
954 status
= U_ZERO_ERROR
;
955 uiter_setState(NULL
, 1, &status
);
956 if (status
!= U_ILLEGAL_ARGUMENT_ERROR
) {
957 errln("error: uiter_setState returned %s instead of U_ILLEGAL_ARGUMENT_ERROR", u_errorName(status
));
959 if (uiter_getState(&sIter
) != UITER_NO_STATE
) {
960 errln("error: uiter_getState did not return UITER_NO_STATE on bad input");
964 // subclass test, and completing API coverage -------------------------------
966 class SubCharIter
: public CharacterIterator
{
968 // public default constructor, to get coverage of CharacterIterator()
969 SubCharIter() : CharacterIterator() {
970 textLength
=end
=LENGTHOF(s
);
972 s
[1]=0xd900; // U+50400
977 // useful stuff, mostly dummy but testing coverage and subclassability
978 virtual UChar
nextPostInc() {
979 if(pos
<LENGTHOF(s
)) {
986 virtual UChar32
next32PostInc() {
987 if(pos
<LENGTHOF(s
)) {
989 U16_NEXT(s
, pos
, LENGTHOF(s
), c
);
996 virtual UBool
hasNext() {
997 return pos
<LENGTHOF(s
);
1000 virtual UChar
first() {
1005 virtual UChar32
first32() {
1008 U16_NEXT(s
, pos
, LENGTHOF(s
), c
);
1013 virtual UChar
setIndex(int32_t position
) {
1014 if(0<=position
&& position
<=LENGTHOF(s
)) {
1016 if(pos
<LENGTHOF(s
)) {
1023 virtual UChar32
setIndex32(int32_t position
) {
1024 if(0<=position
&& position
<=LENGTHOF(s
)) {
1026 if(pos
<LENGTHOF(s
)) {
1028 U16_GET(s
, 0, pos
, LENGTHOF(s
), c
);
1035 virtual UChar
current() const {
1036 if(pos
<LENGTHOF(s
)) {
1043 virtual UChar32
current32() const {
1044 if(pos
<LENGTHOF(s
)) {
1046 U16_GET(s
, 0, pos
, LENGTHOF(s
), c
);
1053 virtual UChar
next() {
1054 if(pos
<LENGTHOF(s
) && ++pos
<LENGTHOF(s
)) {
1061 virtual UChar32
next32() {
1062 if(pos
<LENGTHOF(s
)) {
1063 U16_FWD_1(s
, pos
, LENGTHOF(s
));
1065 if(pos
<LENGTHOF(s
)) {
1068 U16_NEXT(s
, i
, LENGTHOF(s
), c
);
1075 virtual UBool
hasPrevious() {
1079 virtual void getText(UnicodeString
&result
) {
1080 result
.setTo(s
, LENGTHOF(s
));
1083 // dummy implementations of other pure virtual base class functions
1084 virtual UBool
operator==(const ForwardCharacterIterator
&that
) const {
1087 (typeid(*this)==typeid(that
) && pos
==((SubCharIter
&)that
).pos
);
1090 virtual int32_t hashCode() const {
1094 virtual CharacterIterator
*clone() const {
1098 virtual UChar
last() {
1102 virtual UChar32
last32() {
1106 virtual UChar
previous() {
1110 virtual UChar32
previous32() {
1114 virtual int32_t move(int32_t /*delta*/, EOrigin
/*origin*/) {
1118 virtual int32_t move32(int32_t /*delta*/, EOrigin
/*origin*/) {
1123 static UClassID
getStaticClassID() {
1124 return (UClassID
)(&fgClassID
);
1127 virtual UClassID
getDynamicClassID() const {
1128 return getStaticClassID();
1132 // dummy string data
1135 static const char fgClassID
;
1138 const char SubCharIter::fgClassID
= 0;
1140 class SubStringCharIter
: public StringCharacterIterator
{
1142 SubStringCharIter() {
1143 setText(UNICODE_STRING("abc", 3));
1147 class SubUCharCharIter
: public UCharCharacterIterator
{
1149 SubUCharCharIter() {
1154 static const UChar u
[3];
1157 const UChar
SubUCharCharIter::u
[3]={ 0x61, 0x62, 0x63 };
1159 void CharIterTest::TestCharIteratorSubClasses() {
1162 // coverage - call functions that are not otherwise tested
1163 // first[32]PostInc() are default implementations that are overridden
1164 // in ICU's own CharacterIterator subclasses
1166 if(p
->firstPostInc()!=0x61) {
1167 errln("SubCharIter.firstPosInc() failed\n");
1171 p
=new SubCharIter
[2];
1172 if(p
[1].first32PostInc()!=0x61) {
1173 errln("SubCharIter.first32PosInc() failed\n");
1177 // coverage: StringCharacterIterator default constructor
1178 SubStringCharIter sci
;
1179 if(sci
.firstPostInc()!=0x61) {
1180 errln("SubStringCharIter.firstPostInc() failed\n");
1183 // coverage: UCharCharacterIterator default constructor
1184 SubUCharCharIter uci
;
1185 if(uci
.firstPostInc()!=0x61) {
1186 errln("SubUCharCharIter.firstPostInc() failed\n");