X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/b75a7d8f3b4adbae880cab104ce2c6a50eee4db2..a62d09fcbc8ca9da27887e04112ec143e19b1caf:/icuSources/test/intltest/srchtest.cpp diff --git a/icuSources/test/intltest/srchtest.cpp b/icuSources/test/intltest/srchtest.cpp index cb958321..e72f84aa 100644 --- a/icuSources/test/intltest/srchtest.cpp +++ b/icuSources/test/intltest/srchtest.cpp @@ -1,7 +1,7 @@ /* ***************************************************************************** -* Copyright (C) 2001-2003, International Business Machines orporation and others. -* All Rights Reserved. +* Copyright (C) 2001-2016, International Business Machines orporation +* and others. All Rights Reserved. ****************************************************************************/ #include "unicode/utypes.h" @@ -9,11 +9,15 @@ #if !UCONFIG_NO_COLLATION #include "srchtest.h" +#if !UCONFIG_NO_BREAK_ITERATION #include "../cintltst/usrchdat.c" +#endif #include "unicode/stsearch.h" #include "unicode/ustring.h" #include "unicode/schriter.h" +#include "cmemory.h" #include +#include // private definitions ----------------------------------------------------- @@ -23,15 +27,23 @@ if (exec) { \ logln(#test "---"); \ logln((UnicodeString)""); \ - test(); \ + if(areBroken) { \ + dataerrln(__FILE__ " cannot test - failed to create collator."); \ + } else { \ + test(); \ + } \ } \ break; // public contructors and destructors -------------------------------------- -StringSearchTest::StringSearchTest() : +StringSearchTest::StringSearchTest() +#if !UCONFIG_NO_BREAK_ITERATION +: m_en_wordbreaker_(NULL), m_en_characterbreaker_(NULL) +#endif { +#if !UCONFIG_NO_BREAK_ITERATION UErrorCode status = U_ZERO_ERROR; m_en_us_ = (RuleBasedCollator *)Collator::createInstance("en_US", status); @@ -74,10 +86,12 @@ StringSearchTest::StringSearchTest() : m_en_characterbreaker_ = BreakIterator::createCharacterInstance( Locale::getEnglish(), status); #endif +#endif } StringSearchTest::~StringSearchTest() { +#if !UCONFIG_NO_BREAK_ITERATION delete m_en_us_; delete m_fr_fr_; delete m_de_; @@ -86,6 +100,7 @@ StringSearchTest::~StringSearchTest() delete m_en_wordbreaker_; delete m_en_characterbreaker_; #endif +#endif } // public methods ---------------------------------------------------------- @@ -93,16 +108,18 @@ StringSearchTest::~StringSearchTest() void StringSearchTest::runIndexedTest(int32_t index, UBool exec, const char* &name, char* ) { +#if !UCONFIG_NO_BREAK_ITERATION + UBool areBroken = FALSE; if (m_en_us_ == NULL && m_fr_fr_ == NULL && m_de_ == NULL && m_es_ == NULL && m_en_wordbreaker_ == NULL && m_en_characterbreaker_ == NULL && exec) { - errln(__FILE__ " cannot test - failed to create collator."); - name = ""; - return; + areBroken = TRUE; } switch (index) { +#if !UCONFIG_NO_FILE_IO CASE(0, TestOpenClose) +#endif CASE(1, TestInitialization) CASE(2, TestBasic) CASE(3, TestNormExact) @@ -149,10 +166,16 @@ void StringSearchTest::runIndexedTest(int32_t index, UBool exec, CASE(32, TestContractionCanonical) CASE(33, TestUClassID) CASE(34, TestSubclass) + CASE(35, TestCoverage) + CASE(36, TestDiacriticMatch) default: name = ""; break; } +#else + name=""; +#endif } +#if !UCONFIG_NO_BREAK_ITERATION // private methods ------------------------------------------------------ RuleBasedCollator * StringSearchTest::getCollator(const char *collator) @@ -193,33 +216,19 @@ BreakIterator * StringSearchTest::getBreakIterator(const char *breaker) char * StringSearchTest::toCharString(const UnicodeString &text) { - UChar unichars[512]; static char result[1024]; - int count = 0; int index = 0; + int count = 0; int length = text.length(); - text.extract(0, text.length(), unichars, 0); - for (; count < length; count ++) { - UChar ch = unichars[count]; + UChar ch = text[count]; if (ch >= 0x20 && ch <= 0x7e) { result[index ++] = (char)ch; } else { - char digit[5]; - int zerosize; - result[index ++] = '\\'; - result[index ++] = 'u'; - sprintf(digit, "%x", ch); - zerosize = 4 - strlen(digit); - while (zerosize != 0) { - result[index ++] = '0'; - zerosize --; - } - result[index] = 0; - strcat(result, digit); - index += strlen(digit); + sprintf(result+index, "\\u%04x", ch); + index += 6; /* \uxxxx */ } } result[index] = 0; @@ -246,18 +255,26 @@ Collator::ECollationStrength StringSearchTest::getECollationStrength( UBool StringSearchTest::assertEqualWithStringSearch(StringSearch *strsrch, const SearchData *search) { - int count = 0; - UErrorCode status = U_ZERO_ERROR; - int32_t matchindex = search->offset[count]; - UnicodeString matchtext; - + int32_t count = 0; + UErrorCode status = U_ZERO_ERROR; + int32_t matchindex = search->offset[count]; + UnicodeString matchtext; + int32_t matchlength; + + strsrch->setAttribute(USEARCH_ELEMENT_COMPARISON, search->elemCompare, status); + if (U_FAILURE(status)) { + errln("Error setting USEARCH_ELEMENT_COMPARISON attribute %s", u_errorName(status)); + return FALSE; + } + if (strsrch->getMatchedStart() != USEARCH_DONE || strsrch->getMatchedLength() != 0) { errln("Error with the initialization of match start and length"); } - // start of following matches + + // start of next matches while (U_SUCCESS(status) && matchindex >= 0) { - int32_t matchlength = search->size[count]; + matchlength = search->size[count]; strsrch->next(status); if (matchindex != strsrch->getMatchedStart() || matchlength != strsrch->getMatchedLength()) { @@ -265,8 +282,9 @@ UBool StringSearchTest::assertEqualWithStringSearch(StringSearch *strsrch, errln("Text: %s", str); str = toCharString(strsrch->getPattern()); errln("Pattern: %s", str); - errln("Error following match found at %d %d", - strsrch->getMatchedStart(), strsrch->getMatchedLength()); + errln("Error next match found at %d (len:%d); expected %d (len:%d)", + strsrch->getMatchedStart(), strsrch->getMatchedLength(), + matchindex, matchlength); return FALSE; } count ++; @@ -278,7 +296,7 @@ UBool StringSearchTest::assertEqualWithStringSearch(StringSearch *strsrch, matchindex + matchlength, matchtext, 0, matchtext.length())) { - errln("Error getting following matched text"); + errln("Error getting next matched text"); } matchindex = search->offset[count]; @@ -290,15 +308,16 @@ UBool StringSearchTest::assertEqualWithStringSearch(StringSearch *strsrch, errln("Text: %s", str); str = toCharString(strsrch->getPattern()); errln("Pattern: %s", str); - errln("Error following match found at %d %d", + errln("Error next match found at %d (len:%d); expected ", strsrch->getMatchedStart(), strsrch->getMatchedLength()); return FALSE; } - // start of preceding matches + + // start of previous matches count = count == 0 ? 0 : count - 1; matchindex = search->offset[count]; while (U_SUCCESS(status) && matchindex >= 0) { - int32_t matchlength = search->size[count]; + matchlength = search->size[count]; strsrch->previous(status); if (matchindex != strsrch->getMatchedStart() || matchlength != strsrch->getMatchedLength()) { @@ -306,8 +325,9 @@ UBool StringSearchTest::assertEqualWithStringSearch(StringSearch *strsrch, errln("Text: %s", str); str = toCharString(strsrch->getPattern()); errln("Pattern: %s", str); - errln("Error following match found at %d %d", - strsrch->getMatchedStart(), strsrch->getMatchedLength()); + errln("Error previous match found at %d (len:%d); expected %d (len:%d)", + strsrch->getMatchedStart(), strsrch->getMatchedLength(), + matchindex, matchlength); return FALSE; } @@ -318,7 +338,7 @@ UBool StringSearchTest::assertEqualWithStringSearch(StringSearch *strsrch, matchindex + matchlength, matchtext, 0, matchtext.length())) { - errln("Error getting following matched text"); + errln("Error getting previous matched text"); } matchindex = count > 0 ? search->offset[count - 1] : -1; @@ -328,13 +348,113 @@ UBool StringSearchTest::assertEqualWithStringSearch(StringSearch *strsrch, if (strsrch->getMatchedStart() != USEARCH_DONE || strsrch->getMatchedLength() != 0) { char *str = toCharString(strsrch->getText()); - errln("Text: %s", str); + errln("Text: %s", str); + str = toCharString(strsrch->getPattern()); + errln("Pattern: %s", str); + errln("Error previous match found at %d (len:%d); expected ", + strsrch->getMatchedStart(), strsrch->getMatchedLength()); + return FALSE; + } + + int32_t nextStart; + UBool isOverlap = (strsrch->getAttribute(USEARCH_OVERLAP) == USEARCH_ON); + + // start of following matches + count = 0; + matchindex = search->offset[count]; + nextStart = 0; + + while (TRUE) { + strsrch->following(nextStart, status); + + if (matchindex < 0) { + if (strsrch->getMatchedStart() != USEARCH_DONE || + strsrch->getMatchedLength() != 0) { + char *str = toCharString(strsrch->getText()); + errln("Text: %s", str); + str = toCharString(strsrch->getPattern()); + errln("Pattern: %s", str); + errln("Error following match starting at %d (overlap:%d) found at %d (len:%d); expected ", + nextStart, isOverlap, + strsrch->getMatchedStart(), strsrch->getMatchedLength()); + return FALSE; + } + // no more matches + break; + } + + matchlength = search->size[count]; + if (strsrch->getMatchedStart() != matchindex + || strsrch->getMatchedLength() != matchlength + || U_FAILURE(status)) { + char *str = toCharString(strsrch->getText()); + errln("Text: %s\n", str); str = toCharString(strsrch->getPattern()); - errln("Pattern: %s", str); - errln("Error following match found at %d %d", - strsrch->getMatchedStart(), strsrch->getMatchedLength()); + errln("Pattern: %s\n", str); + errln("Error following match starting at %d (overlap: %d) found at %d (len:%d); expected %d (len:%d)\n", + nextStart, isOverlap, + strsrch->getMatchedStart(), strsrch->getMatchedLength(), + matchindex, matchlength); + return FALSE; + } + + if (isOverlap || strsrch->getMatchedLength() == 0) { + nextStart = strsrch->getMatchedStart() + 1; + } else { + nextStart = strsrch->getMatchedStart() + strsrch->getMatchedLength(); + } + + count++; + matchindex = search->offset[count]; + } + + // start preceding matches + count = -1; // last non-negative offset index, could be -1 if no match + while (search->offset[count + 1] >= 0) { + count++; + } + nextStart = strsrch->getText().length(); + + while (TRUE) { + strsrch->preceding(nextStart, status); + + if (count < 0) { + if (strsrch->getMatchedStart() != USEARCH_DONE || strsrch->getMatchedLength() != 0) { + char *str = toCharString(strsrch->getText()); + errln("Text: %s\n", str); + str = toCharString(strsrch->getPattern()); + errln("Pattern: %s\n", str); + errln("Error preceding match starting at %d (overlap: %d) found at %d (len:%d); expected \n", + nextStart, isOverlap, + strsrch->getMatchedStart(), + strsrch->getMatchedLength()); + return FALSE; + } + // no more matches + break; + } + + matchindex = search->offset[count]; + matchlength = search->size[count]; + if (strsrch->getMatchedStart() != matchindex + || strsrch->getMatchedLength() != matchlength + || U_FAILURE(status)) { + char *str = toCharString(strsrch->getText()); + errln("Text: %s\n", str); + str = toCharString(strsrch->getPattern()); + errln("Pattern: %s\n", str); + errln("Error preceding match starting at %d (overlap: %d) found at %d (len:%d); expected %d (len:%d)\n", + nextStart, isOverlap, + strsrch->getMatchedStart(), strsrch->getMatchedLength(), + matchindex, matchlength); return FALSE; + } + + nextStart = matchindex; + count--; } + + strsrch->setAttribute(USEARCH_ELEMENT_COMPARISON, USEARCH_STANDARD_ELEMENT_COMPARISON, status); return TRUE; } @@ -344,7 +464,7 @@ UBool StringSearchTest::assertEqual(const SearchData *search) Collator *collator = getCollator(search->collator); BreakIterator *breaker = getBreakIterator(search->breaker); - StringSearch *strsrch; + StringSearch *strsrch, *strsrch2; UChar temp[128]; #if UCONFIG_NO_BREAK_ITERATION @@ -377,6 +497,20 @@ UBool StringSearchTest::assertEqual(const SearchData *search) delete strsrch; return FALSE; } + + + strsrch2 = strsrch->clone(); + if( strsrch2 == strsrch || *strsrch2 != *strsrch || + !assertEqualWithStringSearch(strsrch2, search) + ) { + infoln("failure with StringSearch.clone()"); + collator->setStrength(getECollationStrength(UCOL_TERTIARY)); + delete strsrch; + delete strsrch2; + return FALSE; + } + delete strsrch2; + collator->setStrength(getECollationStrength(UCOL_TERTIARY)); delete strsrch; return TRUE; @@ -389,6 +523,7 @@ UBool StringSearchTest::assertCanonicalEqual(const SearchData *search) BreakIterator *breaker = getBreakIterator(search->breaker); StringSearch *strsrch; UChar temp[128]; + UBool result = TRUE; #if UCONFIG_NO_BREAK_ITERATION if(search->breaker) { @@ -409,22 +544,27 @@ UBool StringSearchTest::assertCanonicalEqual(const SearchData *search) } #endif collator->setStrength(getECollationStrength(search->strength)); + collator->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status); strsrch = new StringSearch(pattern, text, (RuleBasedCollator *)collator, breaker, status); strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status); if (U_FAILURE(status)) { errln("Error opening string search %s", u_errorName(status)); - return FALSE; + result = FALSE; + goto bail; } if (!assertEqualWithStringSearch(strsrch, search)) { - collator->setStrength(getECollationStrength(UCOL_TERTIARY)); - delete strsrch; - return FALSE; + result = FALSE; + goto bail; } + +bail: collator->setStrength(getECollationStrength(UCOL_TERTIARY)); + collator->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_OFF, status); delete strsrch; - return TRUE; + + return result; } UBool StringSearchTest::assertEqualWithAttribute(const SearchData *search, @@ -675,7 +815,7 @@ void StringSearchTest::TestBasic() while (BASIC[count].text != NULL) { //printf("count %d", count); if (!assertEqual(&BASIC[count])) { - errln("Error at test number %d", count); + infoln("Error at test number %d", count); } count ++; } @@ -692,14 +832,14 @@ void StringSearchTest::TestNormExact() } while (BASIC[count].text != NULL) { if (!assertEqual(&BASIC[count])) { - errln("Error at test number %d", count); + infoln("Error at test number %d", count); } count ++; } count = 0; while (NORMEXACT[count].text != NULL) { if (!assertEqual(&NORMEXACT[count])) { - errln("Error at test number %d", count); + infoln("Error at test number %d", count); } count ++; } @@ -707,7 +847,7 @@ void StringSearchTest::TestNormExact() count = 0; while (NONNORMEXACT[count].text != NULL) { if (!assertEqual(&NONNORMEXACT[count])) { - errln("Error at test number %d", count); + infoln("Error at test number %d", count); } count ++; } @@ -718,7 +858,7 @@ void StringSearchTest::TestStrength() int count = 0; while (STRENGTH[count].text != NULL) { if (!assertEqual(&STRENGTH[count])) { - errln("Error at test number %d", count); + infoln("Error at test number %d", count); } count ++; } @@ -804,7 +944,7 @@ void StringSearchTest::TestBreakIterator() } strsrch->reset(); if (!assertEqualWithStringSearch(strsrch, search)) { - errln("Error at test number %d", count); + infoln("Error at test number %d", count); } delete strsrch; count += 2; @@ -812,7 +952,7 @@ void StringSearchTest::TestBreakIterator() count = 0; while (BREAKITERATOREXACT[count].text != NULL) { if (!assertEqual(&BREAKITERATOREXACT[count])) { - errln("Error at test number %d", count); + infoln("Error at test number %d", count); } count ++; } @@ -832,7 +972,7 @@ void StringSearchTest::TestVariable() while (VARIABLE[count].text != NULL) { logln("variable %d", count); if (!assertEqual(&VARIABLE[count])) { - errln("Error at test number %d", count); + infoln("Error at test number %d", count); } count ++; } @@ -935,9 +1075,7 @@ void StringSearchTest::TestCollator() if (U_FAILURE(status)) { errln("Error opening rule based collator %s", u_errorName(status)); delete strsrch; - if (tailored != NULL) { - delete tailored; - } + delete tailored; return; } @@ -945,16 +1083,12 @@ void StringSearchTest::TestCollator() if (U_FAILURE(status) || (*strsrch->getCollator()) != (*tailored)) { errln("Error setting rule based collator"); delete strsrch; - if (tailored != NULL) { - delete tailored; - } + delete tailored; } strsrch->reset(); if (!assertEqualWithStringSearch(strsrch, &COLLATOR[1])) { delete strsrch; - if (tailored != NULL) { - delete tailored; - } + delete tailored; return; } @@ -963,17 +1097,13 @@ void StringSearchTest::TestCollator() if (U_FAILURE(status) || (*strsrch->getCollator()) != (*m_en_us_)) { errln("Error setting rule based collator"); delete strsrch; - if (tailored != NULL) { - delete tailored; - } + delete tailored; } if (!assertEqualWithStringSearch(strsrch, &COLLATOR[0])) { errln("Error searching collator test"); } delete strsrch; - if (tailored != NULL) { - delete tailored; - } + delete tailored; } void StringSearchTest::TestPattern() @@ -1539,6 +1669,43 @@ void StringSearchTest::TestIgnorable() delete strsrch; delete collator; } + +void StringSearchTest::TestDiacriticMatch() +{ + UChar temp[128]; + UErrorCode status = U_ZERO_ERROR; + int count = 0; + RuleBasedCollator* coll = NULL; + StringSearch *strsrch = NULL; + + UnicodeString pattern("pattern"); + UnicodeString text("text"); + + const SearchData *search; + + search = &(DIACRITICMATCH[count]); + while (search->text != NULL) { + coll = getCollator(search->collator); + coll->setStrength(getECollationStrength(search->strength)); + strsrch = new StringSearch(pattern, text, coll, getBreakIterator(search->breaker), status); + if (U_FAILURE(status)) { + errln("Error opening string search %s", u_errorName(status)); + return; + } + u_unescape(search->text, temp, 128); + text.setTo(temp, u_strlen(temp)); + u_unescape(search->pattern, temp, 128); + pattern.setTo(temp, u_strlen(temp)); + strsrch->setText(text, status); + strsrch->setPattern(pattern, status); + if (!assertEqualWithStringSearch(strsrch, search)) { + errln("Error at test number %d", count); + } + search = &(DIACRITICMATCH[++count]); + delete strsrch; + } + +} void StringSearchTest::TestCanonical() { @@ -1618,6 +1785,10 @@ void StringSearchTest::TestBreakIteratorCanonical() } search = &(BREAKITERATOREXACT[count + 1]); breaker = getBreakIterator(search->breaker); + if (breaker == NULL) { + errln("Error creating BreakIterator"); + return; + } breaker->setText(strsrch->getText()); strsrch->setBreakIterator(breaker, status); if (U_FAILURE(status) || strsrch->getBreakIterator() != breaker) { @@ -1771,6 +1942,8 @@ void StringSearchTest::TestCollatorCanonical() if (tailored != NULL) { delete tailored; } + + return; } strsrch->setCollator(m_en_us_, status); @@ -1933,6 +2106,10 @@ void StringSearchTest::TestGetSetOffsetCanonical() UnicodeString pattern("pattern"); StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, status); + Collator *collator = strsrch->getCollator(); + + collator->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status); + strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status); /* testing out of bounds error */ strsrch->setOffset(-1, status); @@ -1976,7 +2153,7 @@ void StringSearchTest::TestGetSetOffsetCanonical() errln("Error match found at %d %d", strsrch->getMatchedStart(), strsrch->getMatchedLength()); - return; + goto bail; } matchindex = search.offset[count + 1] == -1 ? -1 : search.offset[count + 2]; @@ -1984,7 +2161,7 @@ void StringSearchTest::TestGetSetOffsetCanonical() strsrch->setOffset(search.offset[count + 1] + 1, status); if (strsrch->getOffset() != search.offset[count + 1] + 1) { errln("Error setting offset"); - return; + goto bail; } } @@ -1998,9 +2175,12 @@ void StringSearchTest::TestGetSetOffsetCanonical() errln("Pattern: %s", str); errln("Error match found at %d %d", strsrch->getMatchedStart(), strsrch->getMatchedLength()); - return; + goto bail; } } + +bail: + collator->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_OFF, status); delete strsrch; } @@ -2230,7 +2410,7 @@ void StringSearchTest::TestSubclass() int i; StringCharacterIterator chariter(text); - search.setText(text, status); + search.setText(text, status); if (search.getText() != search2.getText()) { errln("Error setting text"); } @@ -2243,7 +2423,7 @@ void StringSearchTest::TestSubclass() search.reset(); // comparing constructors - for (i = 0; i < (int)(sizeof(expected) / sizeof(expected[0])); i ++) { + for (i = 0; i < UPRV_LENGTHOF(expected); i ++) { if (search.next(status) != expected[i]) { errln("Error getting next match"); } @@ -2254,7 +2434,7 @@ void StringSearchTest::TestSubclass() if (search.next(status) != USEARCH_DONE) { errln("Error should have reached the end of the iteration"); } - for (i = sizeof(expected) / sizeof(expected[0]) - 1; i >= 0; i --) { + for (i = UPRV_LENGTHOF(expected) - 1; i >= 0; i --) { if (search.previous(status) != expected[i]) { errln("Error getting previous match"); } @@ -2267,4 +2447,39 @@ void StringSearchTest::TestSubclass() } } +class StubSearchIterator:public SearchIterator{ +public: + StubSearchIterator(){} + virtual void setOffset(int32_t , UErrorCode &) {}; + virtual int32_t getOffset(void) const {return 0;}; + virtual SearchIterator* safeClone(void) const {return NULL;}; + virtual int32_t handleNext(int32_t , UErrorCode &){return 0;}; + virtual int32_t handlePrev(int32_t , UErrorCode &) {return 0;}; + virtual UClassID getDynamicClassID() const { + static char classID = 0; + return (UClassID)&classID; + } +}; + +void StringSearchTest::TestCoverage(){ + StubSearchIterator stub1, stub2; + UErrorCode status = U_ZERO_ERROR; + + if (stub1 != stub2){ + errln("new StubSearchIterator should be equal"); + } + + stub2.setText(UnicodeString("ABC"), status); + if (U_FAILURE(status)) { + errln("Error: SearchIterator::SetText"); + } + + stub1 = stub2; + if (stub1 != stub2){ + errln("SearchIterator::operator = assigned object should be equal"); + } +} + +#endif /* !UCONFIG_NO_BREAK_ITERATION */ + #endif /* #if !UCONFIG_NO_COLLATION */