diff options
Diffstat (limited to 'Build/source/libs/icu/icu-4.6/test/intltest/citrtest.cpp')
-rw-r--r-- | Build/source/libs/icu/icu-4.6/test/intltest/citrtest.cpp | 1187 |
1 files changed, 1187 insertions, 0 deletions
diff --git a/Build/source/libs/icu/icu-4.6/test/intltest/citrtest.cpp b/Build/source/libs/icu/icu-4.6/test/intltest/citrtest.cpp new file mode 100644 index 00000000000..8f2059fb7c9 --- /dev/null +++ b/Build/source/libs/icu/icu-4.6/test/intltest/citrtest.cpp @@ -0,0 +1,1187 @@ +/**************************************************************************************** + * COPYRIGHT: + * Copyright (c) 1997-2010, International Business Machines Corporation and + * others. All Rights Reserved. + * Modification History: + * + * Date Name Description + * 05/22/2000 Madhu Added tests for testing new API for utf16 support and more + ****************************************************************************************/ + +#include <string.h> +#include <typeinfo> // for 'typeid' to work + +#include "unicode/chariter.h" +#include "unicode/ustring.h" +#include "unicode/unistr.h" +#include "unicode/schriter.h" +#include "unicode/uchriter.h" +#include "unicode/uiter.h" +#include "unicode/putil.h" +#include "citrtest.h" + + +class SCharacterIterator : public CharacterIterator { +public: + SCharacterIterator(const UnicodeString& textStr){ + text = textStr; + pos=0; + textLength = textStr.length(); + begin = 0; + end=textLength; + + } + + virtual ~SCharacterIterator(){}; + + + void setText(const UnicodeString& newText){ + text = newText; + } + + virtual void getText(UnicodeString& result) { + text.extract(0,text.length(),result); + } + static UClassID getStaticClassID(void){ + return (UClassID)(&fgClassID); + } + virtual UClassID getDynamicClassID(void) const{ + return getStaticClassID(); + } + + virtual UBool operator==(const ForwardCharacterIterator& /*that*/) const{ + return TRUE; + } + + virtual CharacterIterator* clone(void) const { + return NULL; + } + virtual int32_t hashCode(void) const{ + return DONE; + } + virtual UChar nextPostInc(void){ return text.charAt(pos++);} + virtual UChar32 next32PostInc(void){return text.char32At(pos++);} + virtual UBool hasNext() { return TRUE;}; + virtual UChar first(){return DONE;}; + virtual UChar32 first32(){return DONE;}; + virtual UChar last(){return DONE;}; + virtual UChar32 last32(){return DONE;}; + virtual UChar setIndex(int32_t /*pos*/){return DONE;}; + virtual UChar32 setIndex32(int32_t /*pos*/){return DONE;}; + virtual UChar current() const{return DONE;}; + virtual UChar32 current32() const{return DONE;}; + virtual UChar next(){return DONE;}; + virtual UChar32 next32(){return DONE;}; + virtual UChar previous(){return DONE;}; + virtual UChar32 previous32(){return DONE;}; + virtual int32_t move(int32_t delta,CharacterIterator::EOrigin origin){ + switch(origin) { + case kStart: + pos = begin + delta; + break; + case kCurrent: + pos += delta; + break; + case kEnd: + pos = end + delta; + break; + default: + break; + } + + if(pos < begin) { + pos = begin; + } else if(pos > end) { + pos = end; + } + + return pos; + }; + virtual int32_t move32(int32_t delta, CharacterIterator::EOrigin origin){ + switch(origin) { + case kStart: + pos = begin; + if(delta > 0) { + UTF_FWD_N(text, pos, end, delta); + } + break; + case kCurrent: + if(delta > 0) { + UTF_FWD_N(text, pos, end, delta); + } else { + UTF_BACK_N(text, begin, pos, -delta); + } + break; + case kEnd: + pos = end; + if(delta < 0) { + UTF_BACK_N(text, begin, pos, -delta); + } + break; + default: + break; + } + + return pos; + }; + virtual UBool hasPrevious() {return TRUE;}; + + SCharacterIterator& operator=(const SCharacterIterator& that){ + text = that.text; + return *this; + } + + +private: + UnicodeString text; + static const char fgClassID; +}; +const char SCharacterIterator::fgClassID=0; + +#define LENGTHOF(array) ((int32_t)(sizeof(array)/sizeof((array)[0]))) + +CharIterTest::CharIterTest() +{ +} +void CharIterTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) +{ + if (exec) logln("TestSuite CharIterTest: "); + switch (index) { + case 0: name = "TestConstructionAndEquality"; if (exec) TestConstructionAndEquality(); break; + case 1: name = "TestConstructionAndEqualityUChariter"; if (exec) TestConstructionAndEqualityUChariter(); break; + case 2: name = "TestIteration"; if (exec) TestIteration(); break; + case 3: name = "TestIterationUChar32"; if (exec) TestIterationUChar32(); break; + case 4: name = "TestUCharIterator"; if (exec) TestUCharIterator(); break; + case 5: name = "TestCoverage"; if(exec) TestCoverage(); break; + case 6: name = "TestCharIteratorSubClasses"; if (exec) TestCharIteratorSubClasses(); break; + default: name = ""; break; //needed to end loop + } +} + +void CharIterTest::TestCoverage(){ + UnicodeString testText("Now is the time for all good men to come to the aid of their country."); + UnicodeString testText2("\\ud800\\udc01deadbeef"); + testText2 = testText2.unescape(); + SCharacterIterator* test = new SCharacterIterator(testText); + if(test->firstPostInc()!= 0x004E){ + errln("Failed: firstPostInc() failed"); + } + if(test->getIndex()!=1){ + errln("Failed: getIndex()."); + } + if(test->getLength()!=testText.length()){ + errln("Failed: getLength()"); + } + test->setToStart(); + if(test->getIndex()!=0){ + errln("Failed: setToStart()."); + } + test->setToEnd(); + if(test->getIndex()!=testText.length()){ + errln("Failed: setToEnd()."); + } + if(test->startIndex() != 0){ + errln("Failed: startIndex()"); + } + test->setText(testText2); + if(test->first32PostInc()!= testText2.char32At(0)){ + errln("Failed: first32PostInc() failed"); + } + + delete test; + +} +void CharIterTest::TestConstructionAndEquality() { + UnicodeString testText("Now is the time for all good men to come to the aid of their country."); + UnicodeString testText2("Don't bother using this string."); + UnicodeString result1, result2, result3; + + CharacterIterator* test1 = new StringCharacterIterator(testText); + CharacterIterator* test1b= new StringCharacterIterator(testText, -1); + CharacterIterator* test1c= new StringCharacterIterator(testText, 100); + CharacterIterator* test1d= new StringCharacterIterator(testText, -2, 100, 5); + CharacterIterator* test1e= new StringCharacterIterator(testText, 100, 20, 5); + CharacterIterator* test2 = new StringCharacterIterator(testText, 5); + CharacterIterator* test3 = new StringCharacterIterator(testText, 2, 20, 5); + CharacterIterator* test4 = new StringCharacterIterator(testText2); + CharacterIterator* test5 = test1->clone(); + + if (test1d->startIndex() < 0) + errln("Construction failed: startIndex is negative"); + if (test1d->endIndex() > testText.length()) + errln("Construction failed: endIndex is greater than the text length"); + if (test1d->getIndex() < test1d->startIndex() || test1d->endIndex() < test1d->getIndex()) + errln("Construction failed: index is invalid"); + + if (*test1 == *test2 || *test1 == *test3 || *test1 == *test4) + errln("Construction or operator== failed: Unequal objects compared equal"); + if (*test1 != *test5) + errln("clone() or equals() failed: Two clones tested unequal"); + + if (test1->hashCode() == test2->hashCode() || test1->hashCode() == test3->hashCode() + || test1->hashCode() == test4->hashCode()) + errln("hashCode() failed: different objects have same hash code"); + + if (test1->hashCode() != test5->hashCode()) + errln("hashCode() failed: identical objects have different hash codes"); + + if(test1->getLength() != testText.length()){ + errln("getLength of CharacterIterator failed"); + } + test1->getText(result1); + test1b->getText(result2); + test1c->getText(result3); + if(result1 != result2 || result1 != result3) + errln("construction failed or getText() failed"); + + + test1->setIndex(5); + if (*test1 != *test2 || *test1 == *test5) + errln("setIndex() failed"); + + *((StringCharacterIterator*)test1) = *((StringCharacterIterator*)test3); + if (*test1 != *test3 || *test1 == *test5) + errln("operator= failed"); + + delete test2; + delete test3; + delete test4; + delete test5; + delete test1b; + delete test1c; + delete test1d; + delete test1e; + + + StringCharacterIterator* testChar1=new StringCharacterIterator(testText); + StringCharacterIterator* testChar2=new StringCharacterIterator(testText2); + StringCharacterIterator* testChar3=(StringCharacterIterator*)test1->clone(); + + testChar1->getText(result1); + testChar2->getText(result2); + testChar3->getText(result3); + if(result1 != result3 || result1 == result2) + errln("getText() failed"); + testChar3->setText(testText2); + testChar3->getText(result3); + if(result1 == result3 || result2 != result3) + errln("setText() or getText() failed"); + testChar3->setText(testText); + testChar3->getText(result3); + if(result1 != result3 || result1 == result2) + errln("setText() or getText() round-trip failed"); + + delete testChar1; + delete testChar2; + delete testChar3; + delete test1; + +} +void CharIterTest::TestConstructionAndEqualityUChariter() { + U_STRING_DECL(testText, "Now is the time for all good men to come to the aid of their country.", 69); + U_STRING_DECL(testText2, "Don't bother using this string.", 31); + + U_STRING_INIT(testText, "Now is the time for all good men to come to the aid of their country.", 69); + U_STRING_INIT(testText2, "Don't bother using this string.", 31); + + UnicodeString result, result4, result5; + + UCharCharacterIterator* test1 = new UCharCharacterIterator(testText, u_strlen(testText)); + UCharCharacterIterator* test2 = new UCharCharacterIterator(testText, u_strlen(testText), 5); + UCharCharacterIterator* test3 = new UCharCharacterIterator(testText, u_strlen(testText), 2, 20, 5); + UCharCharacterIterator* test4 = new UCharCharacterIterator(testText2, u_strlen(testText2)); + UCharCharacterIterator* test5 = (UCharCharacterIterator*)test1->clone(); + UCharCharacterIterator* test6 = new UCharCharacterIterator(*test1); + + // j785: length=-1 will use u_strlen() + UCharCharacterIterator* test7a = new UCharCharacterIterator(testText, -1); + UCharCharacterIterator* test7b = new UCharCharacterIterator(testText, -1); + UCharCharacterIterator* test7c = new UCharCharacterIterator(testText, -1, 2, 20, 5); + + // Bad parameters. + UCharCharacterIterator* test8a = new UCharCharacterIterator(testText, -1, -1, 20, 5); + UCharCharacterIterator* test8b = new UCharCharacterIterator(testText, -1, 2, 100, 5); + UCharCharacterIterator* test8c = new UCharCharacterIterator(testText, -1, 2, 20, 100); + + if (test8a->startIndex() < 0) + errln("Construction failed: startIndex is negative"); + if (test8b->endIndex() != u_strlen(testText)) + errln("Construction failed: endIndex is different from the text length"); + if (test8c->getIndex() < test8c->startIndex() || test8c->endIndex() < test8c->getIndex()) + errln("Construction failed: index is invalid"); + + if (*test1 == *test2 || *test1 == *test3 || *test1 == *test4 ) + errln("Construction or operator== failed: Unequal objects compared equal"); + if (*test1 != *test5 ) + errln("clone() or equals() failed: Two clones tested unequal"); + + if (*test6 != *test1 ) + errln("copy construction or equals() failed: Two copies tested unequal"); + + if (test1->hashCode() == test2->hashCode() || test1->hashCode() == test3->hashCode() + || test1->hashCode() == test4->hashCode()) + errln("hashCode() failed: different objects have same hash code"); + + if (test1->hashCode() != test5->hashCode()) + errln("hashCode() failed: identical objects have different hash codes"); + + test7a->getText(result); + test7b->getText(result4); + test7c->getText(result5); + + if(result != UnicodeString(testText) || result4 != result || result5 != result) + errln("error in construction"); + + test1->getText(result); + test4->getText(result4); + test5->getText(result5); + if(result != result5 || result == result4) + errln("getText() failed"); + test5->setText(testText2, u_strlen(testText2)); + test5->getText(result5); + if(result == result5 || result4 != result5) + errln("setText() or getText() failed"); + test5->setText(testText, u_strlen(testText)); + test5->getText(result5); + if(result != result5 || result == result4) + errln("setText() or getText() round-trip failed"); + + + test1->setIndex(5); + if (*test1 != *test2 || *test1 == *test5) + errln("setIndex() failed"); + test8b->setIndex32(5); + if (test8b->getIndex()!=5) + errln("setIndex32() failed"); + + *test1 = *test3; + if (*test1 != *test3 || *test1 == *test5) + errln("operator= failed"); + + delete test1; + delete test2; + delete test3; + delete test4; + delete test5; + delete test6; + delete test7a; + delete test7b; + delete test7c; + delete test8a; + delete test8b; + delete test8c; +} + + +void CharIterTest::TestIteration() { + UnicodeString text("Now is the time for all good men to come to the aid of their country."); + + UChar c; + int32_t i; + { + StringCharacterIterator iter(text, 5); + + UnicodeString iterText; + iter.getText(iterText); + if (iterText != text) + errln("iter.getText() failed"); + + if (iter.current() != text[(int32_t)5]) + errln("Iterator didn't start out in the right place."); + + c = iter.first(); + i = 0; + + if (iter.startIndex() != 0 || iter.endIndex() != text.length()) + errln("startIndex() or endIndex() failed"); + + logln("Testing forward iteration..."); + do { + if (c == CharacterIterator::DONE && i != text.length()) + errln("Iterator reached end prematurely"); + else if (c != text[i]) + errln((UnicodeString)"Character mismatch at position " + i + + ", iterator has " + UCharToUnicodeString(c) + + ", string has " + UCharToUnicodeString(text[i])); + + if (iter.current() != c) + errln("current() isn't working right"); + if (iter.getIndex() != i) + errln("getIndex() isn't working right"); + + if (c != CharacterIterator::DONE) { + c = iter.next(); + i++; + } + } while (c != CharacterIterator::DONE); + c=iter.next(); + if(c!= CharacterIterator::DONE) + errln("next() didn't return DONE at the end"); + c=iter.setIndex(text.length()+1); + if(c!= CharacterIterator::DONE) + errln("setIndex(len+1) didn't return DONE"); + + c = iter.last(); + i = text.length() - 1; + + logln("Testing backward iteration..."); + do { + if (c == CharacterIterator::DONE && i >= 0) + errln("Iterator reached end prematurely"); + else if (c != text[i]) + errln((UnicodeString)"Character mismatch at position " + i + + ", iterator has " + UCharToUnicodeString(c) + + ", string has " + UCharToUnicodeString(text[i])); + + if (iter.current() != c) + errln("current() isn't working right"); + if (iter.getIndex() != i) + errln("getIndex() isn't working right"); + if(iter.setIndex(i) != c) + errln("setIndex() isn't working right"); + + if (c != CharacterIterator::DONE) { + c = iter.previous(); + i--; + } + } while (c != CharacterIterator::DONE); + + c=iter.previous(); + if(c!= CharacterIterator::DONE) + errln("previous didn't return DONE at the beginning"); + + + //testing firstPostInc, nextPostInc, setTostart + i = 0; + c=iter.firstPostInc(); + if(c != text[i]) + errln((UnicodeString)"firstPostInc failed. Expected->" + + UCharToUnicodeString(text[i]) + " Got->" + UCharToUnicodeString(c)); + if(iter.getIndex() != i+1) + errln((UnicodeString)"getIndex() after firstPostInc() failed"); + + iter.setToStart(); + i=0; + if (iter.startIndex() != 0) + errln("setToStart failed"); + + logln("Testing forward iteration..."); + do { + if (c != CharacterIterator::DONE) + c = iter.nextPostInc(); + + if(c != text[i]) + errln((UnicodeString)"Character mismatch at position " + i + + (UnicodeString)", iterator has " + UCharToUnicodeString(c) + + (UnicodeString)", string has " + UCharToUnicodeString(text[i])); + + i++; + if(iter.getIndex() != i) + errln("getIndex() aftr nextPostInc() isn't working right"); + if(iter.current() != text[i]) + errln("current() after nextPostInc() isn't working right"); + } while (iter.hasNext()); + c=iter.nextPostInc(); + if(c!= CharacterIterator::DONE) + errln("nextPostInc() didn't return DONE at the beginning"); + } + + { + StringCharacterIterator iter(text, 5, 15, 10); + if (iter.startIndex() != 5 || iter.endIndex() != 15) + errln("creation of a restricted-range iterator failed"); + + if (iter.getIndex() != 10 || iter.current() != text[(int32_t)10]) + errln("starting the iterator in the middle didn't work"); + + c = iter.first(); + i = 5; + + logln("Testing forward iteration over a range..."); + do { + if (c == CharacterIterator::DONE && i != 15) + errln("Iterator reached end prematurely"); + else if (c != text[i]) + errln((UnicodeString)"Character mismatch at position " + i + + ", iterator has " + UCharToUnicodeString(c) + + ", string has " + UCharToUnicodeString(text[i])); + + if (iter.current() != c) + errln("current() isn't working right"); + if (iter.getIndex() != i) + errln("getIndex() isn't working right"); + if(iter.setIndex(i) != c) + errln("setIndex() isn't working right"); + + if (c != CharacterIterator::DONE) { + c = iter.next(); + i++; + } + } while (c != CharacterIterator::DONE); + + c = iter.last(); + i = 14; + + logln("Testing backward iteration over a range..."); + do { + if (c == CharacterIterator::DONE && i >= 5) + errln("Iterator reached end prematurely"); + else if (c != text[i]) + errln((UnicodeString)"Character mismatch at position " + i + + ", iterator has " + UCharToUnicodeString(c) + + ", string has " + UCharToUnicodeString(text[i])); + + if (iter.current() != c) + errln("current() isn't working right"); + if (iter.getIndex() != i) + errln("getIndex() isn't working right"); + + if (c != CharacterIterator::DONE) { + c = iter.previous(); + i--; + } + } while (c != CharacterIterator::DONE); + + + } +} + +//Tests for new API for utf-16 support +void CharIterTest::TestIterationUChar32() { + UChar textChars[]={ 0x0061, 0x0062, 0xd841, 0xdc02, 0x20ac, 0xd7ff, 0xd842, 0xdc06, 0xd801, 0xdc00, 0x0061, 0x0000}; + UnicodeString text(textChars); + UChar32 c; + int32_t i; + { + StringCharacterIterator iter(text, 1); + + UnicodeString iterText; + iter.getText(iterText); + if (iterText != text) + errln("iter.getText() failed"); + + if (iter.current32() != text[(int32_t)1]) + errln("Iterator didn't start out in the right place."); + + c=iter.setToStart(); + i=0; + i=iter.move32(1, CharacterIterator::kStart); + c=iter.current32(); + if(c != text.char32At(1) || i!=1) + errln("move32(1, kStart) didn't work correctly expected %X got %X", c, text.char32At(1) ); + + i=iter.move32(2, CharacterIterator::kCurrent); + c=iter.current32(); + if(c != text.char32At(4) || i!=4) + errln("move32(2, kCurrent) didn't work correctly expected %X got %X i=%ld", c, text.char32At(4), i); + + i=iter.move32(-2, CharacterIterator::kCurrent); + c=iter.current32(); + if(c != text.char32At(1) || i!=1) + errln("move32(-2, kCurrent) didn't work correctly expected %X got %X i=%d", c, text.char32At(1), i); + + + i=iter.move32(-2, CharacterIterator::kEnd); + c=iter.current32(); + if(c != text.char32At((text.length()-3)) || i!=(text.length()-3)) + errln("move32(-2, kEnd) didn't work correctly expected %X got %X i=%d", c, text.char32At((text.length()-3)), i); + + + c = iter.first32(); + i = 0; + + if (iter.startIndex() != 0 || iter.endIndex() != text.length()) + errln("startIndex() or endIndex() failed"); + + logln("Testing forward iteration..."); + do { + /* logln("c=%d i=%d char32At=%d", c, i, text.char32At(i)); */ + if (c == CharacterIterator::DONE && i != text.length()) + errln("Iterator reached end prematurely"); + else if(iter.hasNext() == FALSE && i != text.length()) + errln("Iterator reached end prematurely. Failed at hasNext"); + else if (c != text.char32At(i)) + errln("Character mismatch at position %d, iterator has %X, string has %X", i, c, text.char32At(i)); + + if (iter.current32() != c) + errln("current32() isn't working right"); + if(iter.setIndex32(i) != c) + errln("setIndex32() isn't working right"); + if (c != CharacterIterator::DONE) { + c = iter.next32(); + i=UTF16_NEED_MULTIPLE_UCHAR(c) ? i+2 : i+1; + } + } while (c != CharacterIterator::DONE); + if(iter.hasNext() == TRUE) + errln("hasNext() returned true at the end of the string"); + + + + c=iter.setToEnd(); + if(iter.getIndex() != text.length() || iter.hasNext() != FALSE) + errln("setToEnd failed"); + + c=iter.next32(); + if(c!= CharacterIterator::DONE) + errln("next32 didn't return DONE at the end"); + c=iter.setIndex32(text.length()+1); + if(c!= CharacterIterator::DONE) + errln("setIndex32(len+1) didn't return DONE"); + + + c = iter.last32(); + i = text.length()-1; + logln("Testing backward iteration..."); + do { + if (c == CharacterIterator::DONE && i >= 0) + errln((UnicodeString)"Iterator reached start prematurely for i=" + i); + else if(iter.hasPrevious() == FALSE && i>0) + errln((UnicodeString)"Iterator reached start prematurely for i=" + i); + else if (c != text.char32At(i)) + errln("Character mismatch at position %d, iterator has %X, string has %X", i, c, text.char32At(i)); + + if (iter.current32() != c) + errln("current32() isn't working right"); + if(iter.setIndex32(i) != c) + errln("setIndex32() isn't working right"); + if (iter.getIndex() != i) + errln("getIndex() isn't working right"); + if (c != CharacterIterator::DONE) { + c = iter.previous32(); + i=UTF16_NEED_MULTIPLE_UCHAR(c) ? i-2 : i-1; + } + } while (c != CharacterIterator::DONE); + if(iter.hasPrevious() == TRUE) + errln("hasPrevious returned true after reaching the start"); + + c=iter.previous32(); + if(c!= CharacterIterator::DONE) + errln("previous32 didn't return DONE at the beginning"); + + + + + //testing first32PostInc, next32PostInc, setTostart + i = 0; + c=iter.first32PostInc(); + if(c != text.char32At(i)) + errln("first32PostInc failed. Expected->%X Got->%X", text.char32At(i), c); + if(iter.getIndex() != UTF16_CHAR_LENGTH(c) + i) + errln((UnicodeString)"getIndex() after first32PostInc() failed"); + + iter.setToStart(); + i=0; + if (iter.startIndex() != 0) + errln("setToStart failed"); + + logln("Testing forward iteration..."); + do { + if (c != CharacterIterator::DONE) + c = iter.next32PostInc(); + + if(c != text.char32At(i)) + errln("Character mismatch at position %d, iterator has %X, string has %X", i, c, text.char32At(i)); + + i=UTF16_NEED_MULTIPLE_UCHAR(c) ? i+2 : i+1; + if(iter.getIndex() != i) + errln("getIndex() aftr next32PostInc() isn't working right"); + if(iter.current32() != text.char32At(i)) + errln("current() after next32PostInc() isn't working right"); + } while (iter.hasNext()); + c=iter.next32PostInc(); + if(c!= CharacterIterator::DONE) + errln("next32PostInc() didn't return DONE at the beginning"); + + + } + + { + StringCharacterIterator iter(text, 1, 11, 10); + if (iter.startIndex() != 1 || iter.endIndex() != 11) + errln("creation of a restricted-range iterator failed"); + + if (iter.getIndex() != 10 || iter.current32() != text.char32At(10)) + errln("starting the iterator in the middle didn't work"); + + c = iter.first32(); + + i = 1; + + logln("Testing forward iteration over a range..."); + do { + if (c == CharacterIterator::DONE && i != 11) + errln("Iterator reached end prematurely"); + else if(iter.hasNext() == FALSE) + errln("Iterator reached end prematurely"); + else if (c != text.char32At(i)) + errln("Character mismatch at position %d, iterator has %X, string has %X", i, c, text.char32At(i)); + + if (iter.current32() != c) + errln("current32() isn't working right"); + if(iter.setIndex32(i) != c) + errln("setIndex32() isn't working right"); + + if (c != CharacterIterator::DONE) { + c = iter.next32(); + i=UTF16_NEED_MULTIPLE_UCHAR(c) ? i+2 : i+1; + } + } while (c != CharacterIterator::DONE); + c=iter.next32(); + if(c != CharacterIterator::DONE) + errln("error in next32()"); + + + + c=iter.last32(); + i = 10; + logln("Testing backward iteration over a range..."); + do { + if (c == CharacterIterator::DONE && i >= 5) + errln("Iterator reached start prematurely"); + else if(iter.hasPrevious() == FALSE && i > 5) + errln("Iterator reached start prematurely"); + else if (c != text.char32At(i)) + errln("Character mismatch at position %d, iterator has %X, string has %X", i, c, text.char32At(i)); + if (iter.current32() != c) + errln("current32() isn't working right"); + if (iter.getIndex() != i) + errln("getIndex() isn't working right"); + if(iter.setIndex32(i) != c) + errln("setIndex32() isn't working right"); + + if (c != CharacterIterator::DONE) { + c = iter.previous32(); + i=UTF16_NEED_MULTIPLE_UCHAR(c) ? i-2 : i-1; + } + + } while (c != CharacterIterator::DONE); + c=iter.previous32(); + if(c!= CharacterIterator::DONE) + errln("error on previous32"); + + + } +} + +void CharIterTest::TestUCharIterator(UCharIterator *iter, CharacterIterator &ci, + const char *moves, const char *which) { + int32_t m; + UChar32 c, c2; + UBool h, h2; + + for(m=0;; ++m) { + // move both iter and s[index] + switch(moves[m]) { + case '0': + h=iter->hasNext(iter); + h2=ci.hasNext(); + c=iter->current(iter); + c2=ci.current(); + break; + case '|': + h=iter->hasNext(iter); + h2=ci.hasNext(); + c=uiter_current32(iter); + c2=ci.current32(); + break; + + case '+': + h=iter->hasNext(iter); + h2=ci.hasNext(); + c=iter->next(iter); + c2=ci.nextPostInc(); + break; + case '>': + h=iter->hasNext(iter); + h2=ci.hasNext(); + c=uiter_next32(iter); + c2=ci.next32PostInc(); + break; + + case '-': + h=iter->hasPrevious(iter); + h2=ci.hasPrevious(); + c=iter->previous(iter); + c2=ci.previous(); + break; + case '<': + h=iter->hasPrevious(iter); + h2=ci.hasPrevious(); + c=uiter_previous32(iter); + c2=ci.previous32(); + break; + + case '2': + h=h2=FALSE; + c=(UChar32)iter->move(iter, 2, UITER_CURRENT); + c2=(UChar32)ci.move(2, CharacterIterator::kCurrent); + break; + + case '8': + h=h2=FALSE; + c=(UChar32)iter->move(iter, -2, UITER_CURRENT); + c2=(UChar32)ci.move(-2, CharacterIterator::kCurrent); + break; + + case 0: + return; + default: + errln("error: unexpected move character '%c' in \"%s\"", moves[m], moves); + return; + } + + // compare results + if(c2==0xffff) { + c2=(UChar32)-1; + } + if(c!=c2 || h!=h2 || ci.getIndex()!=iter->getIndex(iter, UITER_CURRENT)) { + errln("error: UCharIterator(%s) misbehaving at \"%s\"[%d]='%c'", which, moves, m, moves[m]); + } + } +} + +void CharIterTest::TestUCharIterator() { + // test string of length 8 + UnicodeString s=UnicodeString("a \\U00010001b\\U0010fffdz", "").unescape(); + const char *const moves= + "0+++++++++" // 10 moves per line + "----0-----" + ">>|>>>>>>>" + "<<|<<<<<<<" + "22+>8>-8+2"; + + StringCharacterIterator sci(s), compareCI(s); + + UCharIterator sIter, cIter, rIter; + + uiter_setString(&sIter, s.getBuffer(), s.length()); + uiter_setCharacterIterator(&cIter, &sci); + uiter_setReplaceable(&rIter, &s); + + TestUCharIterator(&sIter, compareCI, moves, "uiter_setString"); + compareCI.setIndex(0); + TestUCharIterator(&cIter, compareCI, moves, "uiter_setCharacterIterator"); + compareCI.setIndex(0); + TestUCharIterator(&rIter, compareCI, moves, "uiter_setReplaceable"); + + // test move & getIndex some more + sIter.start=2; + sIter.index=3; + sIter.limit=5; + if( sIter.getIndex(&sIter, UITER_ZERO)!=0 || + sIter.getIndex(&sIter, UITER_START)!=2 || + sIter.getIndex(&sIter, UITER_CURRENT)!=3 || + sIter.getIndex(&sIter, UITER_LIMIT)!=5 || + sIter.getIndex(&sIter, UITER_LENGTH)!=s.length() + ) { + errln("error: UCharIterator(string).getIndex returns wrong index"); + } + + if( sIter.move(&sIter, 4, UITER_ZERO)!=4 || + sIter.move(&sIter, 1, UITER_START)!=3 || + sIter.move(&sIter, 3, UITER_CURRENT)!=5 || + sIter.move(&sIter, -1, UITER_LIMIT)!=4 || + sIter.move(&sIter, -5, UITER_LENGTH)!=3 || + sIter.move(&sIter, 0, UITER_CURRENT)!=sIter.getIndex(&sIter, UITER_CURRENT) || + sIter.getIndex(&sIter, UITER_CURRENT)!=3 + ) { + errln("error: UCharIterator(string).move sets/returns wrong index"); + } + + sci=StringCharacterIterator(s, 2, 5, 3); + uiter_setCharacterIterator(&cIter, &sci); + if( cIter.getIndex(&cIter, UITER_ZERO)!=0 || + cIter.getIndex(&cIter, UITER_START)!=2 || + cIter.getIndex(&cIter, UITER_CURRENT)!=3 || + cIter.getIndex(&cIter, UITER_LIMIT)!=5 || + cIter.getIndex(&cIter, UITER_LENGTH)!=s.length() + ) { + errln("error: UCharIterator(character iterator).getIndex returns wrong index"); + } + + if( cIter.move(&cIter, 4, UITER_ZERO)!=4 || + cIter.move(&cIter, 1, UITER_START)!=3 || + cIter.move(&cIter, 3, UITER_CURRENT)!=5 || + cIter.move(&cIter, -1, UITER_LIMIT)!=4 || + cIter.move(&cIter, -5, UITER_LENGTH)!=3 || + cIter.move(&cIter, 0, UITER_CURRENT)!=cIter.getIndex(&cIter, UITER_CURRENT) || + cIter.getIndex(&cIter, UITER_CURRENT)!=3 + ) { + errln("error: UCharIterator(character iterator).move sets/returns wrong index"); + } + + + if(cIter.getIndex(&cIter, (enum UCharIteratorOrigin)-1) != -1) + { + errln("error: UCharIterator(char iter).getIndex did not return error value"); + } + + if(cIter.move(&cIter, 0, (enum UCharIteratorOrigin)-1) != -1) + { + errln("error: UCharIterator(char iter).move did not return error value"); + } + + + if(rIter.getIndex(&rIter, (enum UCharIteratorOrigin)-1) != -1) + { + errln("error: UCharIterator(repl iter).getIndex did not return error value"); + } + + if(rIter.move(&rIter, 0, (enum UCharIteratorOrigin)-1) != -1) + { + errln("error: UCharIterator(repl iter).move did not return error value"); + } + + + if(sIter.getIndex(&sIter, (enum UCharIteratorOrigin)-1) != -1) + { + errln("error: UCharIterator(string iter).getIndex did not return error value"); + } + + if(sIter.move(&sIter, 0, (enum UCharIteratorOrigin)-1) != -1) + { + errln("error: UCharIterator(string iter).move did not return error value"); + } + + /* Testing function coverage on bad input */ + UErrorCode status = U_ZERO_ERROR; + uiter_setString(&sIter, NULL, 1); + uiter_setState(&sIter, 1, &status); + if (status != U_UNSUPPORTED_ERROR) { + errln("error: uiter_setState returned %s instead of U_UNSUPPORTED_ERROR", u_errorName(status)); + } + status = U_ZERO_ERROR; + uiter_setState(NULL, 1, &status); + if (status != U_ILLEGAL_ARGUMENT_ERROR) { + errln("error: uiter_setState returned %s instead of U_ILLEGAL_ARGUMENT_ERROR", u_errorName(status)); + } + if (uiter_getState(&sIter) != UITER_NO_STATE) { + errln("error: uiter_getState did not return UITER_NO_STATE on bad input"); + } +} + +// subclass test, and completing API coverage ------------------------------- + +class SubCharIter : public CharacterIterator { +public: + // public default constructor, to get coverage of CharacterIterator() + SubCharIter() : CharacterIterator() { + textLength=end=LENGTHOF(s); + s[0]=0x61; // 'a' + s[1]=0xd900; // U+50400 + s[2]=0xdd00; + s[3]=0x2029; // PS + } + + // useful stuff, mostly dummy but testing coverage and subclassability + virtual UChar nextPostInc() { + if(pos<LENGTHOF(s)) { + return s[pos++]; + } else { + return DONE; + } + } + + virtual UChar32 next32PostInc() { + if(pos<LENGTHOF(s)) { + UChar32 c; + U16_NEXT(s, pos, LENGTHOF(s), c); + return c; + } else { + return DONE; + } + } + + virtual UBool hasNext() { + return pos<LENGTHOF(s); + } + + virtual UChar first() { + pos=0; + return s[0]; + } + + virtual UChar32 first32() { + UChar32 c; + pos=0; + U16_NEXT(s, pos, LENGTHOF(s), c); + pos=0; + return c; + } + + virtual UChar setIndex(int32_t position) { + if(0<=position && position<=LENGTHOF(s)) { + pos=position; + if(pos<LENGTHOF(s)) { + return s[pos]; + } + } + return DONE; + } + + virtual UChar32 setIndex32(int32_t position) { + if(0<=position && position<=LENGTHOF(s)) { + pos=position; + if(pos<LENGTHOF(s)) { + UChar32 c; + U16_GET(s, 0, pos, LENGTHOF(s), c); + return c; + } + } + return DONE; + } + + virtual UChar current() const { + if(pos<LENGTHOF(s)) { + return s[pos]; + } else { + return DONE; + } + } + + virtual UChar32 current32() const { + if(pos<LENGTHOF(s)) { + UChar32 c; + U16_GET(s, 0, pos, LENGTHOF(s), c); + return c; + } else { + return DONE; + } + } + + virtual UChar next() { + if(pos<LENGTHOF(s) && ++pos<LENGTHOF(s)) { + return s[pos]; + } else { + return DONE; + } + } + + virtual UChar32 next32() { + if(pos<LENGTHOF(s)) { + U16_FWD_1(s, pos, LENGTHOF(s)); + } + if(pos<LENGTHOF(s)) { + UChar32 c; + int32_t i=pos; + U16_NEXT(s, i, LENGTHOF(s), c); + return c; + } else { + return DONE; + } + } + + virtual UBool hasPrevious() { + return pos>0; + } + + virtual void getText(UnicodeString &result) { + result.setTo(s, LENGTHOF(s)); + } + + // dummy implementations of other pure virtual base class functions + virtual UBool operator==(const ForwardCharacterIterator &that) const { + return + this==&that || + (typeid(*this)==typeid(that) && pos==((SubCharIter &)that).pos); + } + + virtual int32_t hashCode() const { + return 2; + } + + virtual CharacterIterator *clone() const { + return NULL; + } + + virtual UChar last() { + return 0; + } + + virtual UChar32 last32() { + return 0; + } + + virtual UChar previous() { + return 0; + } + + virtual UChar32 previous32() { + return 0; + } + + virtual int32_t move(int32_t /*delta*/, EOrigin /*origin*/) { + return 0; + } + + virtual int32_t move32(int32_t /*delta*/, EOrigin /*origin*/) { + return 0; + } + + // RTTI + static UClassID getStaticClassID() { + return (UClassID)(&fgClassID); + } + + virtual UClassID getDynamicClassID() const { + return getStaticClassID(); + } + +private: + // dummy string data + UChar s[4]; + + static const char fgClassID; +}; + +const char SubCharIter::fgClassID = 0; + +class SubStringCharIter : public StringCharacterIterator { +public: + SubStringCharIter() { + setText(UNICODE_STRING("abc", 3)); + } +}; + +class SubUCharCharIter : public UCharCharacterIterator { +public: + SubUCharCharIter() { + setText(u, 3); + } + +private: + static const UChar u[3]; +}; + +const UChar SubUCharCharIter::u[3]={ 0x61, 0x62, 0x63 }; + +void CharIterTest::TestCharIteratorSubClasses() { + SubCharIter *p; + + // coverage - call functions that are not otherwise tested + // first[32]PostInc() are default implementations that are overridden + // in ICU's own CharacterIterator subclasses + p=new SubCharIter; + if(p->firstPostInc()!=0x61) { + errln("SubCharIter.firstPosInc() failed\n"); + } + delete p; + + p=new SubCharIter[2]; + if(p[1].first32PostInc()!=0x61) { + errln("SubCharIter.first32PosInc() failed\n"); + } + delete [] p; + + // coverage: StringCharacterIterator default constructor + SubStringCharIter sci; + if(sci.firstPostInc()!=0x61) { + errln("SubStringCharIter.firstPostInc() failed\n"); + } + + // coverage: UCharCharacterIterator default constructor + SubUCharCharIter uci; + if(uci.firstPostInc()!=0x61) { + errln("SubUCharCharIter.firstPostInc() failed\n"); + } +} |