]>
git.saurik.com Git - apple/icu.git/blob - icuSources/test/intltest/citrtest.cpp
1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /****************************************************************************************
5 * Copyright (c) 1997-2014, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 * Modification History:
9 * Date Name Description
10 * 05/22/2000 Madhu Added tests for testing new API for utf16 support and more
11 ****************************************************************************************/
14 #include "utypeinfo.h" // for 'typeid' to work
16 #include "unicode/chariter.h"
17 #include "unicode/ustring.h"
18 #include "unicode/unistr.h"
19 #include "unicode/schriter.h"
20 #include "unicode/uchriter.h"
21 #include "unicode/uiter.h"
22 #include "unicode/putil.h"
23 #include "unicode/utf16.h"
28 class SCharacterIterator
: public CharacterIterator
{
30 SCharacterIterator(const UnicodeString
& textStr
){
33 textLength
= textStr
.length();
39 virtual ~SCharacterIterator(){};
42 void setText(const UnicodeString
& newText
){
46 virtual void getText(UnicodeString
& result
) {
47 text
.extract(0,text
.length(),result
);
49 static UClassID
getStaticClassID(void){
50 return (UClassID
)(&fgClassID
);
52 virtual UClassID
getDynamicClassID(void) const{
53 return getStaticClassID();
56 virtual UBool
operator==(const ForwardCharacterIterator
& /*that*/) const{
60 virtual CharacterIterator
* clone(void) const {
63 virtual int32_t hashCode(void) const{
66 virtual UChar
nextPostInc(void){ return text
.charAt(pos
++);}
67 virtual UChar32
next32PostInc(void){return text
.char32At(pos
++);}
68 virtual UBool
hasNext() { return TRUE
;};
69 virtual UChar
first(){return DONE
;};
70 virtual UChar32
first32(){return DONE
;};
71 virtual UChar
last(){return DONE
;};
72 virtual UChar32
last32(){return DONE
;};
73 virtual UChar
setIndex(int32_t /*pos*/){return DONE
;};
74 virtual UChar32
setIndex32(int32_t /*pos*/){return DONE
;};
75 virtual UChar
current() const{return DONE
;};
76 virtual UChar32
current32() const{return DONE
;};
77 virtual UChar
next(){return DONE
;};
78 virtual UChar32
next32(){return DONE
;};
79 virtual UChar
previous(){return DONE
;};
80 virtual UChar32
previous32(){return DONE
;};
81 virtual int32_t move(int32_t delta
,CharacterIterator::EOrigin origin
){
98 } else if(pos
> end
) {
104 virtual int32_t move32(int32_t delta
, CharacterIterator::EOrigin origin
){
109 U16_FWD_N(text
, pos
, end
, delta
);
114 U16_FWD_N(text
, pos
, end
, delta
);
116 U16_BACK_N(text
, begin
, pos
, -delta
);
122 U16_BACK_N(text
, begin
, pos
, -delta
);
131 virtual UBool
hasPrevious() {return TRUE
;};
133 SCharacterIterator
& operator=(const SCharacterIterator
& that
){
141 static const char fgClassID
;
143 const char SCharacterIterator::fgClassID
=0;
145 CharIterTest::CharIterTest()
148 void CharIterTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
150 if (exec
) logln("TestSuite CharIterTest: ");
152 case 0: name
= "TestConstructionAndEquality"; if (exec
) TestConstructionAndEquality(); break;
153 case 1: name
= "TestConstructionAndEqualityUChariter"; if (exec
) TestConstructionAndEqualityUChariter(); break;
154 case 2: name
= "TestIteration"; if (exec
) TestIteration(); break;
155 case 3: name
= "TestIterationUChar32"; if (exec
) TestIterationUChar32(); break;
156 case 4: name
= "TestUCharIterator"; if (exec
) TestUCharIterator(); break;
157 case 5: name
= "TestCoverage"; if(exec
) TestCoverage(); break;
158 case 6: name
= "TestCharIteratorSubClasses"; if (exec
) TestCharIteratorSubClasses(); break;
159 default: name
= ""; break; //needed to end loop
163 void CharIterTest::TestCoverage(){
164 UnicodeString
testText("Now is the time for all good men to come to the aid of their country.");
165 UnicodeString
testText2("\\ud800\\udc01deadbeef");
166 testText2
= testText2
.unescape();
167 SCharacterIterator
* test
= new SCharacterIterator(testText
);
168 if(test
->firstPostInc()!= 0x004E){
169 errln("Failed: firstPostInc() failed");
171 if(test
->getIndex()!=1){
172 errln("Failed: getIndex().");
174 if(test
->getLength()!=testText
.length()){
175 errln("Failed: getLength()");
178 if(test
->getIndex()!=0){
179 errln("Failed: setToStart().");
182 if(test
->getIndex()!=testText
.length()){
183 errln("Failed: setToEnd().");
185 if(test
->startIndex() != 0){
186 errln("Failed: startIndex()");
188 test
->setText(testText2
);
189 if(test
->first32PostInc()!= testText2
.char32At(0)){
190 errln("Failed: first32PostInc() failed");
196 void CharIterTest::TestConstructionAndEquality() {
197 UnicodeString
testText("Now is the time for all good men to come to the aid of their country.");
198 UnicodeString
testText2("Don't bother using this string.");
199 UnicodeString result1
, result2
, result3
;
201 CharacterIterator
* test1
= new StringCharacterIterator(testText
);
202 CharacterIterator
* test1b
= new StringCharacterIterator(testText
, -1);
203 CharacterIterator
* test1c
= new StringCharacterIterator(testText
, 100);
204 CharacterIterator
* test1d
= new StringCharacterIterator(testText
, -2, 100, 5);
205 CharacterIterator
* test1e
= new StringCharacterIterator(testText
, 100, 20, 5);
206 CharacterIterator
* test2
= new StringCharacterIterator(testText
, 5);
207 CharacterIterator
* test3
= new StringCharacterIterator(testText
, 2, 20, 5);
208 CharacterIterator
* test4
= new StringCharacterIterator(testText2
);
209 CharacterIterator
* test5
= test1
->clone();
211 if (test1d
->startIndex() < 0)
212 errln("Construction failed: startIndex is negative");
213 if (test1d
->endIndex() > testText
.length())
214 errln("Construction failed: endIndex is greater than the text length");
215 if (test1d
->getIndex() < test1d
->startIndex() || test1d
->endIndex() < test1d
->getIndex())
216 errln("Construction failed: index is invalid");
218 if (*test1
== *test2
|| *test1
== *test3
|| *test1
== *test4
)
219 errln("Construction or operator== failed: Unequal objects compared equal");
220 if (*test1
!= *test5
)
221 errln("clone() or equals() failed: Two clones tested unequal");
223 if (test1
->hashCode() == test2
->hashCode() || test1
->hashCode() == test3
->hashCode()
224 || test1
->hashCode() == test4
->hashCode())
225 errln("hashCode() failed: different objects have same hash code");
227 if (test1
->hashCode() != test5
->hashCode())
228 errln("hashCode() failed: identical objects have different hash codes");
230 if(test1
->getLength() != testText
.length()){
231 errln("getLength of CharacterIterator failed");
233 test1
->getText(result1
);
234 test1b
->getText(result2
);
235 test1c
->getText(result3
);
236 if(result1
!= result2
|| result1
!= result3
)
237 errln("construction failed or getText() failed");
241 if (*test1
!= *test2
|| *test1
== *test5
)
242 errln("setIndex() failed");
244 *((StringCharacterIterator
*)test1
) = *((StringCharacterIterator
*)test3
);
245 if (*test1
!= *test3
|| *test1
== *test5
)
246 errln("operator= failed");
258 StringCharacterIterator
* testChar1
=new StringCharacterIterator(testText
);
259 StringCharacterIterator
* testChar2
=new StringCharacterIterator(testText2
);
260 StringCharacterIterator
* testChar3
=(StringCharacterIterator
*)test1
->clone();
262 testChar1
->getText(result1
);
263 testChar2
->getText(result2
);
264 testChar3
->getText(result3
);
265 if(result1
!= result3
|| result1
== result2
)
266 errln("getText() failed");
267 testChar3
->setText(testText2
);
268 testChar3
->getText(result3
);
269 if(result1
== result3
|| result2
!= result3
)
270 errln("setText() or getText() failed");
271 testChar3
->setText(testText
);
272 testChar3
->getText(result3
);
273 if(result1
!= result3
|| result1
== result2
)
274 errln("setText() or getText() round-trip failed");
282 void CharIterTest::TestConstructionAndEqualityUChariter() {
283 U_STRING_DECL(testText
, "Now is the time for all good men to come to the aid of their country.", 69);
284 U_STRING_DECL(testText2
, "Don't bother using this string.", 31);
286 U_STRING_INIT(testText
, "Now is the time for all good men to come to the aid of their country.", 69);
287 U_STRING_INIT(testText2
, "Don't bother using this string.", 31);
289 UnicodeString result
, result4
, result5
;
291 UCharCharacterIterator
* test1
= new UCharCharacterIterator(testText
, u_strlen(testText
));
292 UCharCharacterIterator
* test2
= new UCharCharacterIterator(testText
, u_strlen(testText
), 5);
293 UCharCharacterIterator
* test3
= new UCharCharacterIterator(testText
, u_strlen(testText
), 2, 20, 5);
294 UCharCharacterIterator
* test4
= new UCharCharacterIterator(testText2
, u_strlen(testText2
));
295 UCharCharacterIterator
* test5
= (UCharCharacterIterator
*)test1
->clone();
296 UCharCharacterIterator
* test6
= new UCharCharacterIterator(*test1
);
298 // j785: length=-1 will use u_strlen()
299 UCharCharacterIterator
* test7a
= new UCharCharacterIterator(testText
, -1);
300 UCharCharacterIterator
* test7b
= new UCharCharacterIterator(testText
, -1);
301 UCharCharacterIterator
* test7c
= new UCharCharacterIterator(testText
, -1, 2, 20, 5);
304 UCharCharacterIterator
* test8a
= new UCharCharacterIterator(testText
, -1, -1, 20, 5);
305 UCharCharacterIterator
* test8b
= new UCharCharacterIterator(testText
, -1, 2, 100, 5);
306 UCharCharacterIterator
* test8c
= new UCharCharacterIterator(testText
, -1, 2, 20, 100);
308 if (test8a
->startIndex() < 0)
309 errln("Construction failed: startIndex is negative");
310 if (test8b
->endIndex() != u_strlen(testText
))
311 errln("Construction failed: endIndex is different from the text length");
312 if (test8c
->getIndex() < test8c
->startIndex() || test8c
->endIndex() < test8c
->getIndex())
313 errln("Construction failed: index is invalid");
315 if (*test1
== *test2
|| *test1
== *test3
|| *test1
== *test4
)
316 errln("Construction or operator== failed: Unequal objects compared equal");
317 if (*test1
!= *test5
)
318 errln("clone() or equals() failed: Two clones tested unequal");
320 if (*test6
!= *test1
)
321 errln("copy construction or equals() failed: Two copies tested unequal");
323 if (test1
->hashCode() == test2
->hashCode() || test1
->hashCode() == test3
->hashCode()
324 || test1
->hashCode() == test4
->hashCode())
325 errln("hashCode() failed: different objects have same hash code");
327 if (test1
->hashCode() != test5
->hashCode())
328 errln("hashCode() failed: identical objects have different hash codes");
330 test7a
->getText(result
);
331 test7b
->getText(result4
);
332 test7c
->getText(result5
);
334 if(result
!= UnicodeString(testText
) || result4
!= result
|| result5
!= result
)
335 errln("error in construction");
337 test1
->getText(result
);
338 test4
->getText(result4
);
339 test5
->getText(result5
);
340 if(result
!= result5
|| result
== result4
)
341 errln("getText() failed");
342 test5
->setText(testText2
, u_strlen(testText2
));
343 test5
->getText(result5
);
344 if(result
== result5
|| result4
!= result5
)
345 errln("setText() or getText() failed");
346 test5
->setText(testText
, u_strlen(testText
));
347 test5
->getText(result5
);
348 if(result
!= result5
|| result
== result4
)
349 errln("setText() or getText() round-trip failed");
353 if (*test1
!= *test2
|| *test1
== *test5
)
354 errln("setIndex() failed");
355 test8b
->setIndex32(5);
356 if (test8b
->getIndex()!=5)
357 errln("setIndex32() failed");
360 if (*test1
!= *test3
|| *test1
== *test5
)
361 errln("operator= failed");
378 void CharIterTest::TestIteration() {
379 UnicodeString
text("Now is the time for all good men to come to the aid of their country.");
384 StringCharacterIterator
iter(text
, 5);
386 UnicodeString iterText
;
387 iter
.getText(iterText
);
388 if (iterText
!= text
)
389 errln("iter.getText() failed");
391 if (iter
.current() != text
[(int32_t)5])
392 errln("Iterator didn't start out in the right place.");
397 if (iter
.startIndex() != 0 || iter
.endIndex() != text
.length())
398 errln("startIndex() or endIndex() failed");
400 logln("Testing forward iteration...");
402 if (c
== CharacterIterator::DONE
&& i
!= text
.length())
403 errln("Iterator reached end prematurely");
404 else if (c
!= text
[i
])
405 errln((UnicodeString
)"Character mismatch at position " + i
+
406 ", iterator has " + UCharToUnicodeString(c
) +
407 ", string has " + UCharToUnicodeString(text
[i
]));
409 if (iter
.current() != c
)
410 errln("current() isn't working right");
411 if (iter
.getIndex() != i
)
412 errln("getIndex() isn't working right");
414 if (c
!= CharacterIterator::DONE
) {
418 } while (c
!= CharacterIterator::DONE
);
420 if(c
!= CharacterIterator::DONE
)
421 errln("next() didn't return DONE at the end");
422 c
=iter
.setIndex(text
.length()+1);
423 if(c
!= CharacterIterator::DONE
)
424 errln("setIndex(len+1) didn't return DONE");
427 i
= text
.length() - 1;
429 logln("Testing backward iteration...");
431 if (c
== CharacterIterator::DONE
&& i
>= 0)
432 errln("Iterator reached end prematurely");
433 else if (c
!= text
[i
])
434 errln((UnicodeString
)"Character mismatch at position " + i
+
435 ", iterator has " + UCharToUnicodeString(c
) +
436 ", string has " + UCharToUnicodeString(text
[i
]));
438 if (iter
.current() != c
)
439 errln("current() isn't working right");
440 if (iter
.getIndex() != i
)
441 errln("getIndex() isn't working right");
442 if(iter
.setIndex(i
) != c
)
443 errln("setIndex() isn't working right");
445 if (c
!= CharacterIterator::DONE
) {
449 } while (c
!= CharacterIterator::DONE
);
452 if(c
!= CharacterIterator::DONE
)
453 errln("previous didn't return DONE at the beginning");
456 //testing firstPostInc, nextPostInc, setTostart
458 c
=iter
.firstPostInc();
460 errln((UnicodeString
)"firstPostInc failed. Expected->" +
461 UCharToUnicodeString(text
[i
]) + " Got->" + UCharToUnicodeString(c
));
462 if(iter
.getIndex() != i
+1)
463 errln((UnicodeString
)"getIndex() after firstPostInc() failed");
467 if (iter
.startIndex() != 0)
468 errln("setToStart failed");
470 logln("Testing forward iteration...");
472 if (c
!= CharacterIterator::DONE
)
473 c
= iter
.nextPostInc();
476 errln((UnicodeString
)"Character mismatch at position " + i
+
477 (UnicodeString
)", iterator has " + UCharToUnicodeString(c
) +
478 (UnicodeString
)", string has " + UCharToUnicodeString(text
[i
]));
481 if(iter
.getIndex() != i
)
482 errln("getIndex() aftr nextPostInc() isn't working right");
483 if(iter
.current() != text
[i
])
484 errln("current() after nextPostInc() isn't working right");
485 } while (iter
.hasNext());
486 c
=iter
.nextPostInc();
487 if(c
!= CharacterIterator::DONE
)
488 errln("nextPostInc() didn't return DONE at the beginning");
492 StringCharacterIterator
iter(text
, 5, 15, 10);
493 if (iter
.startIndex() != 5 || iter
.endIndex() != 15)
494 errln("creation of a restricted-range iterator failed");
496 if (iter
.getIndex() != 10 || iter
.current() != text
[(int32_t)10])
497 errln("starting the iterator in the middle didn't work");
502 logln("Testing forward iteration over a range...");
504 if (c
== CharacterIterator::DONE
&& i
!= 15)
505 errln("Iterator reached end prematurely");
506 else if (c
!= text
[i
])
507 errln((UnicodeString
)"Character mismatch at position " + i
+
508 ", iterator has " + UCharToUnicodeString(c
) +
509 ", string has " + UCharToUnicodeString(text
[i
]));
511 if (iter
.current() != c
)
512 errln("current() isn't working right");
513 if (iter
.getIndex() != i
)
514 errln("getIndex() isn't working right");
515 if(iter
.setIndex(i
) != c
)
516 errln("setIndex() isn't working right");
518 if (c
!= CharacterIterator::DONE
) {
522 } while (c
!= CharacterIterator::DONE
);
527 logln("Testing backward iteration over a range...");
529 if (c
== CharacterIterator::DONE
&& i
>= 5)
530 errln("Iterator reached end prematurely");
531 else if (c
!= text
[i
])
532 errln((UnicodeString
)"Character mismatch at position " + i
+
533 ", iterator has " + UCharToUnicodeString(c
) +
534 ", string has " + UCharToUnicodeString(text
[i
]));
536 if (iter
.current() != c
)
537 errln("current() isn't working right");
538 if (iter
.getIndex() != i
)
539 errln("getIndex() isn't working right");
541 if (c
!= CharacterIterator::DONE
) {
545 } while (c
!= CharacterIterator::DONE
);
551 //Tests for new API for utf-16 support
552 void CharIterTest::TestIterationUChar32() {
553 UChar textChars
[]={ 0x0061, 0x0062, 0xd841, 0xdc02, 0x20ac, 0xd7ff, 0xd842, 0xdc06, 0xd801, 0xdc00, 0x0061, 0x0000};
554 UnicodeString
text(textChars
);
558 StringCharacterIterator
iter(text
, 1);
560 UnicodeString iterText
;
561 iter
.getText(iterText
);
562 if (iterText
!= text
)
563 errln("iter.getText() failed");
565 if (iter
.current32() != text
[(int32_t)1])
566 errln("Iterator didn't start out in the right place.");
570 i
=iter
.move32(1, CharacterIterator::kStart
);
572 if(c
!= text
.char32At(1) || i
!=1)
573 errln("move32(1, kStart) didn't work correctly expected %X got %X", c
, text
.char32At(1) );
575 i
=iter
.move32(2, CharacterIterator::kCurrent
);
577 if(c
!= text
.char32At(4) || i
!=4)
578 errln("move32(2, kCurrent) didn't work correctly expected %X got %X i=%ld", c
, text
.char32At(4), i
);
580 i
=iter
.move32(-2, CharacterIterator::kCurrent
);
582 if(c
!= text
.char32At(1) || i
!=1)
583 errln("move32(-2, kCurrent) didn't work correctly expected %X got %X i=%d", c
, text
.char32At(1), i
);
586 i
=iter
.move32(-2, CharacterIterator::kEnd
);
588 if(c
!= text
.char32At((text
.length()-3)) || i
!=(text
.length()-3))
589 errln("move32(-2, kEnd) didn't work correctly expected %X got %X i=%d", c
, text
.char32At((text
.length()-3)), i
);
595 if (iter
.startIndex() != 0 || iter
.endIndex() != text
.length())
596 errln("startIndex() or endIndex() failed");
598 logln("Testing forward iteration...");
600 /* logln("c=%d i=%d char32At=%d", c, i, text.char32At(i)); */
601 if (c
== CharacterIterator::DONE
&& i
!= text
.length())
602 errln("Iterator reached end prematurely");
603 else if(iter
.hasNext() == FALSE
&& i
!= text
.length())
604 errln("Iterator reached end prematurely. Failed at hasNext");
605 else if (c
!= text
.char32At(i
))
606 errln("Character mismatch at position %d, iterator has %X, string has %X", i
, c
, text
.char32At(i
));
608 if (iter
.current32() != c
)
609 errln("current32() isn't working right");
610 if(iter
.setIndex32(i
) != c
)
611 errln("setIndex32() isn't working right");
612 if (c
!= CharacterIterator::DONE
) {
616 } while (c
!= CharacterIterator::DONE
);
617 if(iter
.hasNext() == TRUE
)
618 errln("hasNext() returned true at the end of the string");
623 if(iter
.getIndex() != text
.length() || iter
.hasNext() != FALSE
)
624 errln("setToEnd failed");
627 if(c
!= CharacterIterator::DONE
)
628 errln("next32 didn't return DONE at the end");
629 c
=iter
.setIndex32(text
.length()+1);
630 if(c
!= CharacterIterator::DONE
)
631 errln("setIndex32(len+1) didn't return DONE");
636 logln("Testing backward iteration...");
638 if (c
== CharacterIterator::DONE
&& i
>= 0)
639 errln((UnicodeString
)"Iterator reached start prematurely for i=" + i
);
640 else if(iter
.hasPrevious() == FALSE
&& i
>0)
641 errln((UnicodeString
)"Iterator reached start prematurely for i=" + i
);
642 else if (c
!= text
.char32At(i
))
643 errln("Character mismatch at position %d, iterator has %X, string has %X", i
, c
, text
.char32At(i
));
645 if (iter
.current32() != c
)
646 errln("current32() isn't working right");
647 if(iter
.setIndex32(i
) != c
)
648 errln("setIndex32() isn't working right");
649 if (iter
.getIndex() != i
)
650 errln("getIndex() isn't working right");
651 if (c
!= CharacterIterator::DONE
) {
652 c
= iter
.previous32();
655 } while (c
!= CharacterIterator::DONE
);
656 if(iter
.hasPrevious() == TRUE
)
657 errln("hasPrevious returned true after reaching the start");
660 if(c
!= CharacterIterator::DONE
)
661 errln("previous32 didn't return DONE at the beginning");
666 //testing first32PostInc, next32PostInc, setTostart
668 c
=iter
.first32PostInc();
669 if(c
!= text
.char32At(i
))
670 errln("first32PostInc failed. Expected->%X Got->%X", text
.char32At(i
), c
);
671 if(iter
.getIndex() != U16_LENGTH(c
) + i
)
672 errln((UnicodeString
)"getIndex() after first32PostInc() failed");
676 if (iter
.startIndex() != 0)
677 errln("setToStart failed");
679 logln("Testing forward iteration...");
681 if (c
!= CharacterIterator::DONE
)
682 c
= iter
.next32PostInc();
684 if(c
!= text
.char32At(i
))
685 errln("Character mismatch at position %d, iterator has %X, string has %X", i
, c
, text
.char32At(i
));
688 if(iter
.getIndex() != i
)
689 errln("getIndex() aftr next32PostInc() isn't working right");
690 if(iter
.current32() != text
.char32At(i
))
691 errln("current() after next32PostInc() isn't working right");
692 } while (iter
.hasNext());
693 c
=iter
.next32PostInc();
694 if(c
!= CharacterIterator::DONE
)
695 errln("next32PostInc() didn't return DONE at the beginning");
701 StringCharacterIterator
iter(text
, 1, 11, 10);
702 if (iter
.startIndex() != 1 || iter
.endIndex() != 11)
703 errln("creation of a restricted-range iterator failed");
705 if (iter
.getIndex() != 10 || iter
.current32() != text
.char32At(10))
706 errln("starting the iterator in the middle didn't work");
712 logln("Testing forward iteration over a range...");
714 if (c
== CharacterIterator::DONE
&& i
!= 11)
715 errln("Iterator reached end prematurely");
716 else if(iter
.hasNext() == FALSE
)
717 errln("Iterator reached end prematurely");
718 else if (c
!= text
.char32At(i
))
719 errln("Character mismatch at position %d, iterator has %X, string has %X", i
, c
, text
.char32At(i
));
721 if (iter
.current32() != c
)
722 errln("current32() isn't working right");
723 if(iter
.setIndex32(i
) != c
)
724 errln("setIndex32() isn't working right");
726 if (c
!= CharacterIterator::DONE
) {
730 } while (c
!= CharacterIterator::DONE
);
732 if(c
!= CharacterIterator::DONE
)
733 errln("error in next32()");
739 logln("Testing backward iteration over a range...");
741 if (c
== CharacterIterator::DONE
&& i
>= 5)
742 errln("Iterator reached start prematurely");
743 else if(iter
.hasPrevious() == FALSE
&& i
> 5)
744 errln("Iterator reached start prematurely");
745 else if (c
!= text
.char32At(i
))
746 errln("Character mismatch at position %d, iterator has %X, string has %X", i
, c
, text
.char32At(i
));
747 if (iter
.current32() != c
)
748 errln("current32() isn't working right");
749 if (iter
.getIndex() != i
)
750 errln("getIndex() isn't working right");
751 if(iter
.setIndex32(i
) != c
)
752 errln("setIndex32() isn't working right");
754 if (c
!= CharacterIterator::DONE
) {
755 c
= iter
.previous32();
759 } while (c
!= CharacterIterator::DONE
);
761 if(c
!= CharacterIterator::DONE
)
762 errln("error on previous32");
768 void CharIterTest::TestUCharIterator(UCharIterator
*iter
, CharacterIterator
&ci
,
769 const char *moves
, const char *which
) {
775 // move both iter and s[index]
778 h
=iter
->hasNext(iter
);
780 c
=iter
->current(iter
);
784 h
=iter
->hasNext(iter
);
786 c
=uiter_current32(iter
);
791 h
=iter
->hasNext(iter
);
797 h
=iter
->hasNext(iter
);
799 c
=uiter_next32(iter
);
800 c2
=ci
.next32PostInc();
804 h
=iter
->hasPrevious(iter
);
806 c
=iter
->previous(iter
);
810 h
=iter
->hasPrevious(iter
);
812 c
=uiter_previous32(iter
);
818 c
=(UChar32
)iter
->move(iter
, 2, UITER_CURRENT
);
819 c2
=(UChar32
)ci
.move(2, CharacterIterator::kCurrent
);
824 c
=(UChar32
)iter
->move(iter
, -2, UITER_CURRENT
);
825 c2
=(UChar32
)ci
.move(-2, CharacterIterator::kCurrent
);
831 errln("error: unexpected move character '%c' in \"%s\"", moves
[m
], moves
);
839 if(c
!=c2
|| h
!=h2
|| ci
.getIndex()!=iter
->getIndex(iter
, UITER_CURRENT
)) {
840 errln("error: UCharIterator(%s) misbehaving at \"%s\"[%d]='%c'", which
, moves
, m
, moves
[m
]);
845 void CharIterTest::TestUCharIterator() {
846 // test string of length 8
847 UnicodeString s
=UnicodeString("a \\U00010001b\\U0010fffdz", "").unescape();
848 const char *const moves
=
849 "0+++++++++" // 10 moves per line
855 StringCharacterIterator
sci(s
), compareCI(s
);
857 UCharIterator sIter
, cIter
, rIter
;
859 uiter_setString(&sIter
, s
.getBuffer(), s
.length());
860 uiter_setCharacterIterator(&cIter
, &sci
);
861 uiter_setReplaceable(&rIter
, &s
);
863 TestUCharIterator(&sIter
, compareCI
, moves
, "uiter_setString");
864 compareCI
.setIndex(0);
865 TestUCharIterator(&cIter
, compareCI
, moves
, "uiter_setCharacterIterator");
866 compareCI
.setIndex(0);
867 TestUCharIterator(&rIter
, compareCI
, moves
, "uiter_setReplaceable");
869 // test move & getIndex some more
873 if( sIter
.getIndex(&sIter
, UITER_ZERO
)!=0 ||
874 sIter
.getIndex(&sIter
, UITER_START
)!=2 ||
875 sIter
.getIndex(&sIter
, UITER_CURRENT
)!=3 ||
876 sIter
.getIndex(&sIter
, UITER_LIMIT
)!=5 ||
877 sIter
.getIndex(&sIter
, UITER_LENGTH
)!=s
.length()
879 errln("error: UCharIterator(string).getIndex returns wrong index");
882 if( sIter
.move(&sIter
, 4, UITER_ZERO
)!=4 ||
883 sIter
.move(&sIter
, 1, UITER_START
)!=3 ||
884 sIter
.move(&sIter
, 3, UITER_CURRENT
)!=5 ||
885 sIter
.move(&sIter
, -1, UITER_LIMIT
)!=4 ||
886 sIter
.move(&sIter
, -5, UITER_LENGTH
)!=3 ||
887 sIter
.move(&sIter
, 0, UITER_CURRENT
)!=sIter
.getIndex(&sIter
, UITER_CURRENT
) ||
888 sIter
.getIndex(&sIter
, UITER_CURRENT
)!=3
890 errln("error: UCharIterator(string).move sets/returns wrong index");
893 sci
=StringCharacterIterator(s
, 2, 5, 3);
894 uiter_setCharacterIterator(&cIter
, &sci
);
895 if( cIter
.getIndex(&cIter
, UITER_ZERO
)!=0 ||
896 cIter
.getIndex(&cIter
, UITER_START
)!=2 ||
897 cIter
.getIndex(&cIter
, UITER_CURRENT
)!=3 ||
898 cIter
.getIndex(&cIter
, UITER_LIMIT
)!=5 ||
899 cIter
.getIndex(&cIter
, UITER_LENGTH
)!=s
.length()
901 errln("error: UCharIterator(character iterator).getIndex returns wrong index");
904 if( cIter
.move(&cIter
, 4, UITER_ZERO
)!=4 ||
905 cIter
.move(&cIter
, 1, UITER_START
)!=3 ||
906 cIter
.move(&cIter
, 3, UITER_CURRENT
)!=5 ||
907 cIter
.move(&cIter
, -1, UITER_LIMIT
)!=4 ||
908 cIter
.move(&cIter
, -5, UITER_LENGTH
)!=3 ||
909 cIter
.move(&cIter
, 0, UITER_CURRENT
)!=cIter
.getIndex(&cIter
, UITER_CURRENT
) ||
910 cIter
.getIndex(&cIter
, UITER_CURRENT
)!=3
912 errln("error: UCharIterator(character iterator).move sets/returns wrong index");
916 if(cIter
.getIndex(&cIter
, (enum UCharIteratorOrigin
)-1) != -1)
918 errln("error: UCharIterator(char iter).getIndex did not return error value");
921 if(cIter
.move(&cIter
, 0, (enum UCharIteratorOrigin
)-1) != -1)
923 errln("error: UCharIterator(char iter).move did not return error value");
927 if(rIter
.getIndex(&rIter
, (enum UCharIteratorOrigin
)-1) != -1)
929 errln("error: UCharIterator(repl iter).getIndex did not return error value");
932 if(rIter
.move(&rIter
, 0, (enum UCharIteratorOrigin
)-1) != -1)
934 errln("error: UCharIterator(repl iter).move did not return error value");
938 if(sIter
.getIndex(&sIter
, (enum UCharIteratorOrigin
)-1) != -1)
940 errln("error: UCharIterator(string iter).getIndex did not return error value");
943 if(sIter
.move(&sIter
, 0, (enum UCharIteratorOrigin
)-1) != -1)
945 errln("error: UCharIterator(string iter).move did not return error value");
948 /* Testing function coverage on bad input */
949 UErrorCode status
= U_ZERO_ERROR
;
950 uiter_setString(&sIter
, NULL
, 1);
951 uiter_setState(&sIter
, 1, &status
);
952 if (status
!= U_UNSUPPORTED_ERROR
) {
953 errln("error: uiter_setState returned %s instead of U_UNSUPPORTED_ERROR", u_errorName(status
));
955 status
= U_ZERO_ERROR
;
956 uiter_setState(NULL
, 1, &status
);
957 if (status
!= U_ILLEGAL_ARGUMENT_ERROR
) {
958 errln("error: uiter_setState returned %s instead of U_ILLEGAL_ARGUMENT_ERROR", u_errorName(status
));
960 if (uiter_getState(&sIter
) != UITER_NO_STATE
) {
961 errln("error: uiter_getState did not return UITER_NO_STATE on bad input");
965 // subclass test, and completing API coverage -------------------------------
967 class SubCharIter
: public CharacterIterator
{
969 // public default constructor, to get coverage of CharacterIterator()
970 SubCharIter() : CharacterIterator() {
971 textLength
=end
=UPRV_LENGTHOF(s
);
973 s
[1]=0xd900; // U+50400
978 // useful stuff, mostly dummy but testing coverage and subclassability
979 virtual UChar
nextPostInc() {
980 if(pos
<UPRV_LENGTHOF(s
)) {
987 virtual UChar32
next32PostInc() {
988 if(pos
<UPRV_LENGTHOF(s
)) {
990 U16_NEXT(s
, pos
, UPRV_LENGTHOF(s
), c
);
997 virtual UBool
hasNext() {
998 return pos
<UPRV_LENGTHOF(s
);
1001 virtual UChar
first() {
1006 virtual UChar32
first32() {
1009 U16_NEXT(s
, pos
, UPRV_LENGTHOF(s
), c
);
1014 virtual UChar
setIndex(int32_t position
) {
1015 if(0<=position
&& position
<=UPRV_LENGTHOF(s
)) {
1017 if(pos
<UPRV_LENGTHOF(s
)) {
1024 virtual UChar32
setIndex32(int32_t position
) {
1025 if(0<=position
&& position
<=UPRV_LENGTHOF(s
)) {
1027 if(pos
<UPRV_LENGTHOF(s
)) {
1029 U16_GET(s
, 0, pos
, UPRV_LENGTHOF(s
), c
);
1036 virtual UChar
current() const {
1037 if(pos
<UPRV_LENGTHOF(s
)) {
1044 virtual UChar32
current32() const {
1045 if(pos
<UPRV_LENGTHOF(s
)) {
1047 U16_GET(s
, 0, pos
, UPRV_LENGTHOF(s
), c
);
1054 virtual UChar
next() {
1055 if(pos
<UPRV_LENGTHOF(s
) && ++pos
<UPRV_LENGTHOF(s
)) {
1062 virtual UChar32
next32() {
1063 if(pos
<UPRV_LENGTHOF(s
)) {
1064 U16_FWD_1(s
, pos
, UPRV_LENGTHOF(s
));
1066 if(pos
<UPRV_LENGTHOF(s
)) {
1069 U16_NEXT(s
, i
, UPRV_LENGTHOF(s
), c
);
1076 virtual UBool
hasPrevious() {
1080 virtual void getText(UnicodeString
&result
) {
1081 result
.setTo(s
, UPRV_LENGTHOF(s
));
1084 // dummy implementations of other pure virtual base class functions
1085 virtual UBool
operator==(const ForwardCharacterIterator
&that
) const {
1088 (typeid(*this)==typeid(that
) && pos
==((SubCharIter
&)that
).pos
);
1091 virtual int32_t hashCode() const {
1095 virtual CharacterIterator
*clone() const {
1099 virtual UChar
last() {
1103 virtual UChar32
last32() {
1107 virtual UChar
previous() {
1111 virtual UChar32
previous32() {
1115 virtual int32_t move(int32_t /*delta*/, EOrigin
/*origin*/) {
1119 virtual int32_t move32(int32_t /*delta*/, EOrigin
/*origin*/) {
1124 static UClassID
getStaticClassID() {
1125 return (UClassID
)(&fgClassID
);
1128 virtual UClassID
getDynamicClassID() const {
1129 return getStaticClassID();
1133 // dummy string data
1136 static const char fgClassID
;
1139 const char SubCharIter::fgClassID
= 0;
1141 class SubStringCharIter
: public StringCharacterIterator
{
1143 SubStringCharIter() {
1144 setText(UNICODE_STRING("abc", 3));
1148 class SubUCharCharIter
: public UCharCharacterIterator
{
1150 SubUCharCharIter() {
1155 static const UChar u
[3];
1158 const UChar
SubUCharCharIter::u
[3]={ 0x61, 0x62, 0x63 };
1160 void CharIterTest::TestCharIteratorSubClasses() {
1163 // coverage - call functions that are not otherwise tested
1164 // first[32]PostInc() are default implementations that are overridden
1165 // in ICU's own CharacterIterator subclasses
1167 if(p
->firstPostInc()!=0x61) {
1168 errln("SubCharIter.firstPosInc() failed\n");
1172 p
=new SubCharIter
[2];
1173 if(p
[1].first32PostInc()!=0x61) {
1174 errln("SubCharIter.first32PosInc() failed\n");
1178 // coverage: StringCharacterIterator default constructor
1179 SubStringCharIter sci
;
1180 if(sci
.firstPostInc()!=0x61) {
1181 errln("SubStringCharIter.firstPostInc() failed\n");
1184 // coverage: UCharCharacterIterator default constructor
1185 SubUCharCharIter uci
;
1186 if(uci
.firstPostInc()!=0x61) {
1187 errln("SubUCharCharIter.firstPostInc() failed\n");