]>
git.saurik.com Git - apple/icu.git/blob - icuSources/test/intltest/citrtest.cpp
1 /****************************************************************************************
3 * Copyright (c) 1997-2014, 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"
26 class SCharacterIterator
: public CharacterIterator
{
28 SCharacterIterator(const UnicodeString
& textStr
){
31 textLength
= textStr
.length();
37 virtual ~SCharacterIterator(){};
40 void setText(const UnicodeString
& newText
){
44 virtual void getText(UnicodeString
& result
) {
45 text
.extract(0,text
.length(),result
);
47 static UClassID
getStaticClassID(void){
48 return (UClassID
)(&fgClassID
);
50 virtual UClassID
getDynamicClassID(void) const{
51 return getStaticClassID();
54 virtual UBool
operator==(const ForwardCharacterIterator
& /*that*/) const{
58 virtual CharacterIterator
* clone(void) const {
61 virtual int32_t hashCode(void) const{
64 virtual UChar
nextPostInc(void){ return text
.charAt(pos
++);}
65 virtual UChar32
next32PostInc(void){return text
.char32At(pos
++);}
66 virtual UBool
hasNext() { return TRUE
;};
67 virtual UChar
first(){return DONE
;};
68 virtual UChar32
first32(){return DONE
;};
69 virtual UChar
last(){return DONE
;};
70 virtual UChar32
last32(){return DONE
;};
71 virtual UChar
setIndex(int32_t /*pos*/){return DONE
;};
72 virtual UChar32
setIndex32(int32_t /*pos*/){return DONE
;};
73 virtual UChar
current() const{return DONE
;};
74 virtual UChar32
current32() const{return DONE
;};
75 virtual UChar
next(){return DONE
;};
76 virtual UChar32
next32(){return DONE
;};
77 virtual UChar
previous(){return DONE
;};
78 virtual UChar32
previous32(){return DONE
;};
79 virtual int32_t move(int32_t delta
,CharacterIterator::EOrigin origin
){
96 } else if(pos
> end
) {
102 virtual int32_t move32(int32_t delta
, CharacterIterator::EOrigin origin
){
107 U16_FWD_N(text
, pos
, end
, delta
);
112 U16_FWD_N(text
, pos
, end
, delta
);
114 U16_BACK_N(text
, begin
, pos
, -delta
);
120 U16_BACK_N(text
, begin
, pos
, -delta
);
129 virtual UBool
hasPrevious() {return TRUE
;};
131 SCharacterIterator
& operator=(const SCharacterIterator
& that
){
139 static const char fgClassID
;
141 const char SCharacterIterator::fgClassID
=0;
143 CharIterTest::CharIterTest()
146 void CharIterTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
148 if (exec
) logln("TestSuite CharIterTest: ");
150 case 0: name
= "TestConstructionAndEquality"; if (exec
) TestConstructionAndEquality(); break;
151 case 1: name
= "TestConstructionAndEqualityUChariter"; if (exec
) TestConstructionAndEqualityUChariter(); break;
152 case 2: name
= "TestIteration"; if (exec
) TestIteration(); break;
153 case 3: name
= "TestIterationUChar32"; if (exec
) TestIterationUChar32(); break;
154 case 4: name
= "TestUCharIterator"; if (exec
) TestUCharIterator(); break;
155 case 5: name
= "TestCoverage"; if(exec
) TestCoverage(); break;
156 case 6: name
= "TestCharIteratorSubClasses"; if (exec
) TestCharIteratorSubClasses(); break;
157 default: name
= ""; break; //needed to end loop
161 void CharIterTest::TestCoverage(){
162 UnicodeString
testText("Now is the time for all good men to come to the aid of their country.");
163 UnicodeString
testText2("\\ud800\\udc01deadbeef");
164 testText2
= testText2
.unescape();
165 SCharacterIterator
* test
= new SCharacterIterator(testText
);
166 if(test
->firstPostInc()!= 0x004E){
167 errln("Failed: firstPostInc() failed");
169 if(test
->getIndex()!=1){
170 errln("Failed: getIndex().");
172 if(test
->getLength()!=testText
.length()){
173 errln("Failed: getLength()");
176 if(test
->getIndex()!=0){
177 errln("Failed: setToStart().");
180 if(test
->getIndex()!=testText
.length()){
181 errln("Failed: setToEnd().");
183 if(test
->startIndex() != 0){
184 errln("Failed: startIndex()");
186 test
->setText(testText2
);
187 if(test
->first32PostInc()!= testText2
.char32At(0)){
188 errln("Failed: first32PostInc() failed");
194 void CharIterTest::TestConstructionAndEquality() {
195 UnicodeString
testText("Now is the time for all good men to come to the aid of their country.");
196 UnicodeString
testText2("Don't bother using this string.");
197 UnicodeString result1
, result2
, result3
;
199 CharacterIterator
* test1
= new StringCharacterIterator(testText
);
200 CharacterIterator
* test1b
= new StringCharacterIterator(testText
, -1);
201 CharacterIterator
* test1c
= new StringCharacterIterator(testText
, 100);
202 CharacterIterator
* test1d
= new StringCharacterIterator(testText
, -2, 100, 5);
203 CharacterIterator
* test1e
= new StringCharacterIterator(testText
, 100, 20, 5);
204 CharacterIterator
* test2
= new StringCharacterIterator(testText
, 5);
205 CharacterIterator
* test3
= new StringCharacterIterator(testText
, 2, 20, 5);
206 CharacterIterator
* test4
= new StringCharacterIterator(testText2
);
207 CharacterIterator
* test5
= test1
->clone();
209 if (test1d
->startIndex() < 0)
210 errln("Construction failed: startIndex is negative");
211 if (test1d
->endIndex() > testText
.length())
212 errln("Construction failed: endIndex is greater than the text length");
213 if (test1d
->getIndex() < test1d
->startIndex() || test1d
->endIndex() < test1d
->getIndex())
214 errln("Construction failed: index is invalid");
216 if (*test1
== *test2
|| *test1
== *test3
|| *test1
== *test4
)
217 errln("Construction or operator== failed: Unequal objects compared equal");
218 if (*test1
!= *test5
)
219 errln("clone() or equals() failed: Two clones tested unequal");
221 if (test1
->hashCode() == test2
->hashCode() || test1
->hashCode() == test3
->hashCode()
222 || test1
->hashCode() == test4
->hashCode())
223 errln("hashCode() failed: different objects have same hash code");
225 if (test1
->hashCode() != test5
->hashCode())
226 errln("hashCode() failed: identical objects have different hash codes");
228 if(test1
->getLength() != testText
.length()){
229 errln("getLength of CharacterIterator failed");
231 test1
->getText(result1
);
232 test1b
->getText(result2
);
233 test1c
->getText(result3
);
234 if(result1
!= result2
|| result1
!= result3
)
235 errln("construction failed or getText() failed");
239 if (*test1
!= *test2
|| *test1
== *test5
)
240 errln("setIndex() failed");
242 *((StringCharacterIterator
*)test1
) = *((StringCharacterIterator
*)test3
);
243 if (*test1
!= *test3
|| *test1
== *test5
)
244 errln("operator= failed");
256 StringCharacterIterator
* testChar1
=new StringCharacterIterator(testText
);
257 StringCharacterIterator
* testChar2
=new StringCharacterIterator(testText2
);
258 StringCharacterIterator
* testChar3
=(StringCharacterIterator
*)test1
->clone();
260 testChar1
->getText(result1
);
261 testChar2
->getText(result2
);
262 testChar3
->getText(result3
);
263 if(result1
!= result3
|| result1
== result2
)
264 errln("getText() failed");
265 testChar3
->setText(testText2
);
266 testChar3
->getText(result3
);
267 if(result1
== result3
|| result2
!= result3
)
268 errln("setText() or getText() failed");
269 testChar3
->setText(testText
);
270 testChar3
->getText(result3
);
271 if(result1
!= result3
|| result1
== result2
)
272 errln("setText() or getText() round-trip failed");
280 void CharIterTest::TestConstructionAndEqualityUChariter() {
281 U_STRING_DECL(testText
, "Now is the time for all good men to come to the aid of their country.", 69);
282 U_STRING_DECL(testText2
, "Don't bother using this string.", 31);
284 U_STRING_INIT(testText
, "Now is the time for all good men to come to the aid of their country.", 69);
285 U_STRING_INIT(testText2
, "Don't bother using this string.", 31);
287 UnicodeString result
, result4
, result5
;
289 UCharCharacterIterator
* test1
= new UCharCharacterIterator(testText
, u_strlen(testText
));
290 UCharCharacterIterator
* test2
= new UCharCharacterIterator(testText
, u_strlen(testText
), 5);
291 UCharCharacterIterator
* test3
= new UCharCharacterIterator(testText
, u_strlen(testText
), 2, 20, 5);
292 UCharCharacterIterator
* test4
= new UCharCharacterIterator(testText2
, u_strlen(testText2
));
293 UCharCharacterIterator
* test5
= (UCharCharacterIterator
*)test1
->clone();
294 UCharCharacterIterator
* test6
= new UCharCharacterIterator(*test1
);
296 // j785: length=-1 will use u_strlen()
297 UCharCharacterIterator
* test7a
= new UCharCharacterIterator(testText
, -1);
298 UCharCharacterIterator
* test7b
= new UCharCharacterIterator(testText
, -1);
299 UCharCharacterIterator
* test7c
= new UCharCharacterIterator(testText
, -1, 2, 20, 5);
302 UCharCharacterIterator
* test8a
= new UCharCharacterIterator(testText
, -1, -1, 20, 5);
303 UCharCharacterIterator
* test8b
= new UCharCharacterIterator(testText
, -1, 2, 100, 5);
304 UCharCharacterIterator
* test8c
= new UCharCharacterIterator(testText
, -1, 2, 20, 100);
306 if (test8a
->startIndex() < 0)
307 errln("Construction failed: startIndex is negative");
308 if (test8b
->endIndex() != u_strlen(testText
))
309 errln("Construction failed: endIndex is different from the text length");
310 if (test8c
->getIndex() < test8c
->startIndex() || test8c
->endIndex() < test8c
->getIndex())
311 errln("Construction failed: index is invalid");
313 if (*test1
== *test2
|| *test1
== *test3
|| *test1
== *test4
)
314 errln("Construction or operator== failed: Unequal objects compared equal");
315 if (*test1
!= *test5
)
316 errln("clone() or equals() failed: Two clones tested unequal");
318 if (*test6
!= *test1
)
319 errln("copy construction or equals() failed: Two copies tested unequal");
321 if (test1
->hashCode() == test2
->hashCode() || test1
->hashCode() == test3
->hashCode()
322 || test1
->hashCode() == test4
->hashCode())
323 errln("hashCode() failed: different objects have same hash code");
325 if (test1
->hashCode() != test5
->hashCode())
326 errln("hashCode() failed: identical objects have different hash codes");
328 test7a
->getText(result
);
329 test7b
->getText(result4
);
330 test7c
->getText(result5
);
332 if(result
!= UnicodeString(testText
) || result4
!= result
|| result5
!= result
)
333 errln("error in construction");
335 test1
->getText(result
);
336 test4
->getText(result4
);
337 test5
->getText(result5
);
338 if(result
!= result5
|| result
== result4
)
339 errln("getText() failed");
340 test5
->setText(testText2
, u_strlen(testText2
));
341 test5
->getText(result5
);
342 if(result
== result5
|| result4
!= result5
)
343 errln("setText() or getText() failed");
344 test5
->setText(testText
, u_strlen(testText
));
345 test5
->getText(result5
);
346 if(result
!= result5
|| result
== result4
)
347 errln("setText() or getText() round-trip failed");
351 if (*test1
!= *test2
|| *test1
== *test5
)
352 errln("setIndex() failed");
353 test8b
->setIndex32(5);
354 if (test8b
->getIndex()!=5)
355 errln("setIndex32() failed");
358 if (*test1
!= *test3
|| *test1
== *test5
)
359 errln("operator= failed");
376 void CharIterTest::TestIteration() {
377 UnicodeString
text("Now is the time for all good men to come to the aid of their country.");
382 StringCharacterIterator
iter(text
, 5);
384 UnicodeString iterText
;
385 iter
.getText(iterText
);
386 if (iterText
!= text
)
387 errln("iter.getText() failed");
389 if (iter
.current() != text
[(int32_t)5])
390 errln("Iterator didn't start out in the right place.");
395 if (iter
.startIndex() != 0 || iter
.endIndex() != text
.length())
396 errln("startIndex() or endIndex() failed");
398 logln("Testing forward iteration...");
400 if (c
== CharacterIterator::DONE
&& i
!= text
.length())
401 errln("Iterator reached end prematurely");
402 else if (c
!= text
[i
])
403 errln((UnicodeString
)"Character mismatch at position " + i
+
404 ", iterator has " + UCharToUnicodeString(c
) +
405 ", string has " + UCharToUnicodeString(text
[i
]));
407 if (iter
.current() != c
)
408 errln("current() isn't working right");
409 if (iter
.getIndex() != i
)
410 errln("getIndex() isn't working right");
412 if (c
!= CharacterIterator::DONE
) {
416 } while (c
!= CharacterIterator::DONE
);
418 if(c
!= CharacterIterator::DONE
)
419 errln("next() didn't return DONE at the end");
420 c
=iter
.setIndex(text
.length()+1);
421 if(c
!= CharacterIterator::DONE
)
422 errln("setIndex(len+1) didn't return DONE");
425 i
= text
.length() - 1;
427 logln("Testing backward iteration...");
429 if (c
== CharacterIterator::DONE
&& i
>= 0)
430 errln("Iterator reached end prematurely");
431 else if (c
!= text
[i
])
432 errln((UnicodeString
)"Character mismatch at position " + i
+
433 ", iterator has " + UCharToUnicodeString(c
) +
434 ", string has " + UCharToUnicodeString(text
[i
]));
436 if (iter
.current() != c
)
437 errln("current() isn't working right");
438 if (iter
.getIndex() != i
)
439 errln("getIndex() isn't working right");
440 if(iter
.setIndex(i
) != c
)
441 errln("setIndex() isn't working right");
443 if (c
!= CharacterIterator::DONE
) {
447 } while (c
!= CharacterIterator::DONE
);
450 if(c
!= CharacterIterator::DONE
)
451 errln("previous didn't return DONE at the beginning");
454 //testing firstPostInc, nextPostInc, setTostart
456 c
=iter
.firstPostInc();
458 errln((UnicodeString
)"firstPostInc failed. Expected->" +
459 UCharToUnicodeString(text
[i
]) + " Got->" + UCharToUnicodeString(c
));
460 if(iter
.getIndex() != i
+1)
461 errln((UnicodeString
)"getIndex() after firstPostInc() failed");
465 if (iter
.startIndex() != 0)
466 errln("setToStart failed");
468 logln("Testing forward iteration...");
470 if (c
!= CharacterIterator::DONE
)
471 c
= iter
.nextPostInc();
474 errln((UnicodeString
)"Character mismatch at position " + i
+
475 (UnicodeString
)", iterator has " + UCharToUnicodeString(c
) +
476 (UnicodeString
)", string has " + UCharToUnicodeString(text
[i
]));
479 if(iter
.getIndex() != i
)
480 errln("getIndex() aftr nextPostInc() isn't working right");
481 if(iter
.current() != text
[i
])
482 errln("current() after nextPostInc() isn't working right");
483 } while (iter
.hasNext());
484 c
=iter
.nextPostInc();
485 if(c
!= CharacterIterator::DONE
)
486 errln("nextPostInc() didn't return DONE at the beginning");
490 StringCharacterIterator
iter(text
, 5, 15, 10);
491 if (iter
.startIndex() != 5 || iter
.endIndex() != 15)
492 errln("creation of a restricted-range iterator failed");
494 if (iter
.getIndex() != 10 || iter
.current() != text
[(int32_t)10])
495 errln("starting the iterator in the middle didn't work");
500 logln("Testing forward iteration over a range...");
502 if (c
== CharacterIterator::DONE
&& i
!= 15)
503 errln("Iterator reached end prematurely");
504 else if (c
!= text
[i
])
505 errln((UnicodeString
)"Character mismatch at position " + i
+
506 ", iterator has " + UCharToUnicodeString(c
) +
507 ", string has " + UCharToUnicodeString(text
[i
]));
509 if (iter
.current() != c
)
510 errln("current() isn't working right");
511 if (iter
.getIndex() != i
)
512 errln("getIndex() isn't working right");
513 if(iter
.setIndex(i
) != c
)
514 errln("setIndex() isn't working right");
516 if (c
!= CharacterIterator::DONE
) {
520 } while (c
!= CharacterIterator::DONE
);
525 logln("Testing backward iteration over a range...");
527 if (c
== CharacterIterator::DONE
&& i
>= 5)
528 errln("Iterator reached end prematurely");
529 else if (c
!= text
[i
])
530 errln((UnicodeString
)"Character mismatch at position " + i
+
531 ", iterator has " + UCharToUnicodeString(c
) +
532 ", string has " + UCharToUnicodeString(text
[i
]));
534 if (iter
.current() != c
)
535 errln("current() isn't working right");
536 if (iter
.getIndex() != i
)
537 errln("getIndex() isn't working right");
539 if (c
!= CharacterIterator::DONE
) {
543 } while (c
!= CharacterIterator::DONE
);
549 //Tests for new API for utf-16 support
550 void CharIterTest::TestIterationUChar32() {
551 UChar textChars
[]={ 0x0061, 0x0062, 0xd841, 0xdc02, 0x20ac, 0xd7ff, 0xd842, 0xdc06, 0xd801, 0xdc00, 0x0061, 0x0000};
552 UnicodeString
text(textChars
);
556 StringCharacterIterator
iter(text
, 1);
558 UnicodeString iterText
;
559 iter
.getText(iterText
);
560 if (iterText
!= text
)
561 errln("iter.getText() failed");
563 if (iter
.current32() != text
[(int32_t)1])
564 errln("Iterator didn't start out in the right place.");
568 i
=iter
.move32(1, CharacterIterator::kStart
);
570 if(c
!= text
.char32At(1) || i
!=1)
571 errln("move32(1, kStart) didn't work correctly expected %X got %X", c
, text
.char32At(1) );
573 i
=iter
.move32(2, CharacterIterator::kCurrent
);
575 if(c
!= text
.char32At(4) || i
!=4)
576 errln("move32(2, kCurrent) didn't work correctly expected %X got %X i=%ld", c
, text
.char32At(4), i
);
578 i
=iter
.move32(-2, CharacterIterator::kCurrent
);
580 if(c
!= text
.char32At(1) || i
!=1)
581 errln("move32(-2, kCurrent) didn't work correctly expected %X got %X i=%d", c
, text
.char32At(1), i
);
584 i
=iter
.move32(-2, CharacterIterator::kEnd
);
586 if(c
!= text
.char32At((text
.length()-3)) || i
!=(text
.length()-3))
587 errln("move32(-2, kEnd) didn't work correctly expected %X got %X i=%d", c
, text
.char32At((text
.length()-3)), i
);
593 if (iter
.startIndex() != 0 || iter
.endIndex() != text
.length())
594 errln("startIndex() or endIndex() failed");
596 logln("Testing forward iteration...");
598 /* logln("c=%d i=%d char32At=%d", c, i, text.char32At(i)); */
599 if (c
== CharacterIterator::DONE
&& i
!= text
.length())
600 errln("Iterator reached end prematurely");
601 else if(iter
.hasNext() == FALSE
&& i
!= text
.length())
602 errln("Iterator reached end prematurely. Failed at hasNext");
603 else if (c
!= text
.char32At(i
))
604 errln("Character mismatch at position %d, iterator has %X, string has %X", i
, c
, text
.char32At(i
));
606 if (iter
.current32() != c
)
607 errln("current32() isn't working right");
608 if(iter
.setIndex32(i
) != c
)
609 errln("setIndex32() isn't working right");
610 if (c
!= CharacterIterator::DONE
) {
612 i
=UTF16_NEED_MULTIPLE_UCHAR(c
) ? i
+2 : i
+1;
614 } while (c
!= CharacterIterator::DONE
);
615 if(iter
.hasNext() == TRUE
)
616 errln("hasNext() returned true at the end of the string");
621 if(iter
.getIndex() != text
.length() || iter
.hasNext() != FALSE
)
622 errln("setToEnd failed");
625 if(c
!= CharacterIterator::DONE
)
626 errln("next32 didn't return DONE at the end");
627 c
=iter
.setIndex32(text
.length()+1);
628 if(c
!= CharacterIterator::DONE
)
629 errln("setIndex32(len+1) didn't return DONE");
634 logln("Testing backward iteration...");
636 if (c
== CharacterIterator::DONE
&& i
>= 0)
637 errln((UnicodeString
)"Iterator reached start prematurely for i=" + i
);
638 else if(iter
.hasPrevious() == FALSE
&& i
>0)
639 errln((UnicodeString
)"Iterator reached start prematurely for i=" + i
);
640 else if (c
!= text
.char32At(i
))
641 errln("Character mismatch at position %d, iterator has %X, string has %X", i
, c
, text
.char32At(i
));
643 if (iter
.current32() != c
)
644 errln("current32() isn't working right");
645 if(iter
.setIndex32(i
) != c
)
646 errln("setIndex32() isn't working right");
647 if (iter
.getIndex() != i
)
648 errln("getIndex() isn't working right");
649 if (c
!= CharacterIterator::DONE
) {
650 c
= iter
.previous32();
651 i
=UTF16_NEED_MULTIPLE_UCHAR(c
) ? i
-2 : i
-1;
653 } while (c
!= CharacterIterator::DONE
);
654 if(iter
.hasPrevious() == TRUE
)
655 errln("hasPrevious returned true after reaching the start");
658 if(c
!= CharacterIterator::DONE
)
659 errln("previous32 didn't return DONE at the beginning");
664 //testing first32PostInc, next32PostInc, setTostart
666 c
=iter
.first32PostInc();
667 if(c
!= text
.char32At(i
))
668 errln("first32PostInc failed. Expected->%X Got->%X", text
.char32At(i
), c
);
669 if(iter
.getIndex() != U16_LENGTH(c
) + i
)
670 errln((UnicodeString
)"getIndex() after first32PostInc() failed");
674 if (iter
.startIndex() != 0)
675 errln("setToStart failed");
677 logln("Testing forward iteration...");
679 if (c
!= CharacterIterator::DONE
)
680 c
= iter
.next32PostInc();
682 if(c
!= text
.char32At(i
))
683 errln("Character mismatch at position %d, iterator has %X, string has %X", i
, c
, text
.char32At(i
));
685 i
=UTF16_NEED_MULTIPLE_UCHAR(c
) ? i
+2 : i
+1;
686 if(iter
.getIndex() != i
)
687 errln("getIndex() aftr next32PostInc() isn't working right");
688 if(iter
.current32() != text
.char32At(i
))
689 errln("current() after next32PostInc() isn't working right");
690 } while (iter
.hasNext());
691 c
=iter
.next32PostInc();
692 if(c
!= CharacterIterator::DONE
)
693 errln("next32PostInc() didn't return DONE at the beginning");
699 StringCharacterIterator
iter(text
, 1, 11, 10);
700 if (iter
.startIndex() != 1 || iter
.endIndex() != 11)
701 errln("creation of a restricted-range iterator failed");
703 if (iter
.getIndex() != 10 || iter
.current32() != text
.char32At(10))
704 errln("starting the iterator in the middle didn't work");
710 logln("Testing forward iteration over a range...");
712 if (c
== CharacterIterator::DONE
&& i
!= 11)
713 errln("Iterator reached end prematurely");
714 else if(iter
.hasNext() == FALSE
)
715 errln("Iterator reached end prematurely");
716 else if (c
!= text
.char32At(i
))
717 errln("Character mismatch at position %d, iterator has %X, string has %X", i
, c
, text
.char32At(i
));
719 if (iter
.current32() != c
)
720 errln("current32() isn't working right");
721 if(iter
.setIndex32(i
) != c
)
722 errln("setIndex32() isn't working right");
724 if (c
!= CharacterIterator::DONE
) {
726 i
=UTF16_NEED_MULTIPLE_UCHAR(c
) ? i
+2 : i
+1;
728 } while (c
!= CharacterIterator::DONE
);
730 if(c
!= CharacterIterator::DONE
)
731 errln("error in next32()");
737 logln("Testing backward iteration over a range...");
739 if (c
== CharacterIterator::DONE
&& i
>= 5)
740 errln("Iterator reached start prematurely");
741 else if(iter
.hasPrevious() == FALSE
&& i
> 5)
742 errln("Iterator reached start prematurely");
743 else if (c
!= text
.char32At(i
))
744 errln("Character mismatch at position %d, iterator has %X, string has %X", i
, c
, text
.char32At(i
));
745 if (iter
.current32() != c
)
746 errln("current32() isn't working right");
747 if (iter
.getIndex() != i
)
748 errln("getIndex() isn't working right");
749 if(iter
.setIndex32(i
) != c
)
750 errln("setIndex32() isn't working right");
752 if (c
!= CharacterIterator::DONE
) {
753 c
= iter
.previous32();
754 i
=UTF16_NEED_MULTIPLE_UCHAR(c
) ? i
-2 : i
-1;
757 } while (c
!= CharacterIterator::DONE
);
759 if(c
!= CharacterIterator::DONE
)
760 errln("error on previous32");
766 void CharIterTest::TestUCharIterator(UCharIterator
*iter
, CharacterIterator
&ci
,
767 const char *moves
, const char *which
) {
773 // move both iter and s[index]
776 h
=iter
->hasNext(iter
);
778 c
=iter
->current(iter
);
782 h
=iter
->hasNext(iter
);
784 c
=uiter_current32(iter
);
789 h
=iter
->hasNext(iter
);
795 h
=iter
->hasNext(iter
);
797 c
=uiter_next32(iter
);
798 c2
=ci
.next32PostInc();
802 h
=iter
->hasPrevious(iter
);
804 c
=iter
->previous(iter
);
808 h
=iter
->hasPrevious(iter
);
810 c
=uiter_previous32(iter
);
816 c
=(UChar32
)iter
->move(iter
, 2, UITER_CURRENT
);
817 c2
=(UChar32
)ci
.move(2, CharacterIterator::kCurrent
);
822 c
=(UChar32
)iter
->move(iter
, -2, UITER_CURRENT
);
823 c2
=(UChar32
)ci
.move(-2, CharacterIterator::kCurrent
);
829 errln("error: unexpected move character '%c' in \"%s\"", moves
[m
], moves
);
837 if(c
!=c2
|| h
!=h2
|| ci
.getIndex()!=iter
->getIndex(iter
, UITER_CURRENT
)) {
838 errln("error: UCharIterator(%s) misbehaving at \"%s\"[%d]='%c'", which
, moves
, m
, moves
[m
]);
843 void CharIterTest::TestUCharIterator() {
844 // test string of length 8
845 UnicodeString s
=UnicodeString("a \\U00010001b\\U0010fffdz", "").unescape();
846 const char *const moves
=
847 "0+++++++++" // 10 moves per line
853 StringCharacterIterator
sci(s
), compareCI(s
);
855 UCharIterator sIter
, cIter
, rIter
;
857 uiter_setString(&sIter
, s
.getBuffer(), s
.length());
858 uiter_setCharacterIterator(&cIter
, &sci
);
859 uiter_setReplaceable(&rIter
, &s
);
861 TestUCharIterator(&sIter
, compareCI
, moves
, "uiter_setString");
862 compareCI
.setIndex(0);
863 TestUCharIterator(&cIter
, compareCI
, moves
, "uiter_setCharacterIterator");
864 compareCI
.setIndex(0);
865 TestUCharIterator(&rIter
, compareCI
, moves
, "uiter_setReplaceable");
867 // test move & getIndex some more
871 if( sIter
.getIndex(&sIter
, UITER_ZERO
)!=0 ||
872 sIter
.getIndex(&sIter
, UITER_START
)!=2 ||
873 sIter
.getIndex(&sIter
, UITER_CURRENT
)!=3 ||
874 sIter
.getIndex(&sIter
, UITER_LIMIT
)!=5 ||
875 sIter
.getIndex(&sIter
, UITER_LENGTH
)!=s
.length()
877 errln("error: UCharIterator(string).getIndex returns wrong index");
880 if( sIter
.move(&sIter
, 4, UITER_ZERO
)!=4 ||
881 sIter
.move(&sIter
, 1, UITER_START
)!=3 ||
882 sIter
.move(&sIter
, 3, UITER_CURRENT
)!=5 ||
883 sIter
.move(&sIter
, -1, UITER_LIMIT
)!=4 ||
884 sIter
.move(&sIter
, -5, UITER_LENGTH
)!=3 ||
885 sIter
.move(&sIter
, 0, UITER_CURRENT
)!=sIter
.getIndex(&sIter
, UITER_CURRENT
) ||
886 sIter
.getIndex(&sIter
, UITER_CURRENT
)!=3
888 errln("error: UCharIterator(string).move sets/returns wrong index");
891 sci
=StringCharacterIterator(s
, 2, 5, 3);
892 uiter_setCharacterIterator(&cIter
, &sci
);
893 if( cIter
.getIndex(&cIter
, UITER_ZERO
)!=0 ||
894 cIter
.getIndex(&cIter
, UITER_START
)!=2 ||
895 cIter
.getIndex(&cIter
, UITER_CURRENT
)!=3 ||
896 cIter
.getIndex(&cIter
, UITER_LIMIT
)!=5 ||
897 cIter
.getIndex(&cIter
, UITER_LENGTH
)!=s
.length()
899 errln("error: UCharIterator(character iterator).getIndex returns wrong index");
902 if( cIter
.move(&cIter
, 4, UITER_ZERO
)!=4 ||
903 cIter
.move(&cIter
, 1, UITER_START
)!=3 ||
904 cIter
.move(&cIter
, 3, UITER_CURRENT
)!=5 ||
905 cIter
.move(&cIter
, -1, UITER_LIMIT
)!=4 ||
906 cIter
.move(&cIter
, -5, UITER_LENGTH
)!=3 ||
907 cIter
.move(&cIter
, 0, UITER_CURRENT
)!=cIter
.getIndex(&cIter
, UITER_CURRENT
) ||
908 cIter
.getIndex(&cIter
, UITER_CURRENT
)!=3
910 errln("error: UCharIterator(character iterator).move sets/returns wrong index");
914 if(cIter
.getIndex(&cIter
, (enum UCharIteratorOrigin
)-1) != -1)
916 errln("error: UCharIterator(char iter).getIndex did not return error value");
919 if(cIter
.move(&cIter
, 0, (enum UCharIteratorOrigin
)-1) != -1)
921 errln("error: UCharIterator(char iter).move did not return error value");
925 if(rIter
.getIndex(&rIter
, (enum UCharIteratorOrigin
)-1) != -1)
927 errln("error: UCharIterator(repl iter).getIndex did not return error value");
930 if(rIter
.move(&rIter
, 0, (enum UCharIteratorOrigin
)-1) != -1)
932 errln("error: UCharIterator(repl iter).move did not return error value");
936 if(sIter
.getIndex(&sIter
, (enum UCharIteratorOrigin
)-1) != -1)
938 errln("error: UCharIterator(string iter).getIndex did not return error value");
941 if(sIter
.move(&sIter
, 0, (enum UCharIteratorOrigin
)-1) != -1)
943 errln("error: UCharIterator(string iter).move did not return error value");
946 /* Testing function coverage on bad input */
947 UErrorCode status
= U_ZERO_ERROR
;
948 uiter_setString(&sIter
, NULL
, 1);
949 uiter_setState(&sIter
, 1, &status
);
950 if (status
!= U_UNSUPPORTED_ERROR
) {
951 errln("error: uiter_setState returned %s instead of U_UNSUPPORTED_ERROR", u_errorName(status
));
953 status
= U_ZERO_ERROR
;
954 uiter_setState(NULL
, 1, &status
);
955 if (status
!= U_ILLEGAL_ARGUMENT_ERROR
) {
956 errln("error: uiter_setState returned %s instead of U_ILLEGAL_ARGUMENT_ERROR", u_errorName(status
));
958 if (uiter_getState(&sIter
) != UITER_NO_STATE
) {
959 errln("error: uiter_getState did not return UITER_NO_STATE on bad input");
963 // subclass test, and completing API coverage -------------------------------
965 class SubCharIter
: public CharacterIterator
{
967 // public default constructor, to get coverage of CharacterIterator()
968 SubCharIter() : CharacterIterator() {
969 textLength
=end
=UPRV_LENGTHOF(s
);
971 s
[1]=0xd900; // U+50400
976 // useful stuff, mostly dummy but testing coverage and subclassability
977 virtual UChar
nextPostInc() {
978 if(pos
<UPRV_LENGTHOF(s
)) {
985 virtual UChar32
next32PostInc() {
986 if(pos
<UPRV_LENGTHOF(s
)) {
988 U16_NEXT(s
, pos
, UPRV_LENGTHOF(s
), c
);
995 virtual UBool
hasNext() {
996 return pos
<UPRV_LENGTHOF(s
);
999 virtual UChar
first() {
1004 virtual UChar32
first32() {
1007 U16_NEXT(s
, pos
, UPRV_LENGTHOF(s
), c
);
1012 virtual UChar
setIndex(int32_t position
) {
1013 if(0<=position
&& position
<=UPRV_LENGTHOF(s
)) {
1015 if(pos
<UPRV_LENGTHOF(s
)) {
1022 virtual UChar32
setIndex32(int32_t position
) {
1023 if(0<=position
&& position
<=UPRV_LENGTHOF(s
)) {
1025 if(pos
<UPRV_LENGTHOF(s
)) {
1027 U16_GET(s
, 0, pos
, UPRV_LENGTHOF(s
), c
);
1034 virtual UChar
current() const {
1035 if(pos
<UPRV_LENGTHOF(s
)) {
1042 virtual UChar32
current32() const {
1043 if(pos
<UPRV_LENGTHOF(s
)) {
1045 U16_GET(s
, 0, pos
, UPRV_LENGTHOF(s
), c
);
1052 virtual UChar
next() {
1053 if(pos
<UPRV_LENGTHOF(s
) && ++pos
<UPRV_LENGTHOF(s
)) {
1060 virtual UChar32
next32() {
1061 if(pos
<UPRV_LENGTHOF(s
)) {
1062 U16_FWD_1(s
, pos
, UPRV_LENGTHOF(s
));
1064 if(pos
<UPRV_LENGTHOF(s
)) {
1067 U16_NEXT(s
, i
, UPRV_LENGTHOF(s
), c
);
1074 virtual UBool
hasPrevious() {
1078 virtual void getText(UnicodeString
&result
) {
1079 result
.setTo(s
, UPRV_LENGTHOF(s
));
1082 // dummy implementations of other pure virtual base class functions
1083 virtual UBool
operator==(const ForwardCharacterIterator
&that
) const {
1086 (typeid(*this)==typeid(that
) && pos
==((SubCharIter
&)that
).pos
);
1089 virtual int32_t hashCode() const {
1093 virtual CharacterIterator
*clone() const {
1097 virtual UChar
last() {
1101 virtual UChar32
last32() {
1105 virtual UChar
previous() {
1109 virtual UChar32
previous32() {
1113 virtual int32_t move(int32_t /*delta*/, EOrigin
/*origin*/) {
1117 virtual int32_t move32(int32_t /*delta*/, EOrigin
/*origin*/) {
1122 static UClassID
getStaticClassID() {
1123 return (UClassID
)(&fgClassID
);
1126 virtual UClassID
getDynamicClassID() const {
1127 return getStaticClassID();
1131 // dummy string data
1134 static const char fgClassID
;
1137 const char SubCharIter::fgClassID
= 0;
1139 class SubStringCharIter
: public StringCharacterIterator
{
1141 SubStringCharIter() {
1142 setText(UNICODE_STRING("abc", 3));
1146 class SubUCharCharIter
: public UCharCharacterIterator
{
1148 SubUCharCharIter() {
1153 static const UChar u
[3];
1156 const UChar
SubUCharCharIter::u
[3]={ 0x61, 0x62, 0x63 };
1158 void CharIterTest::TestCharIteratorSubClasses() {
1161 // coverage - call functions that are not otherwise tested
1162 // first[32]PostInc() are default implementations that are overridden
1163 // in ICU's own CharacterIterator subclasses
1165 if(p
->firstPostInc()!=0x61) {
1166 errln("SubCharIter.firstPosInc() failed\n");
1170 p
=new SubCharIter
[2];
1171 if(p
[1].first32PostInc()!=0x61) {
1172 errln("SubCharIter.first32PosInc() failed\n");
1176 // coverage: StringCharacterIterator default constructor
1177 SubStringCharIter sci
;
1178 if(sci
.firstPostInc()!=0x61) {
1179 errln("SubStringCharIter.firstPostInc() failed\n");
1182 // coverage: UCharCharacterIterator default constructor
1183 SubUCharCharIter uci
;
1184 if(uci
.firstPostInc()!=0x61) {
1185 errln("SubUCharCharIter.firstPostInc() failed\n");