/* ***************************************************************************** * Copyright (C) 2001, International Business Machines orporation and others. * All Rights Reserved. ****************************************************************************/ #include "srchtest.h" #include "../cintltst/usrchdat.c" #include "unicode/stsearch.h" #include "unicode/ustring.h" #include "unicode/schriter.h" #include // private definitions ----------------------------------------------------- #define CASE(id,test) \ case id: \ name = #test; \ if (exec) { \ logln(#test "---"); \ logln((UnicodeString)""); \ test(); \ } \ break; // public contructors and destructors -------------------------------------- StringSearchTest::StringSearchTest() { UErrorCode status = U_ZERO_ERROR; m_en_us_ = (RuleBasedCollator *)Collator::createInstance("en_US", status); m_fr_fr_ = (RuleBasedCollator *)Collator::createInstance("fr_FR", status); m_de_ = (RuleBasedCollator *)Collator::createInstance("de_DE", status); m_es_ = (RuleBasedCollator *)Collator::createInstance("es_ES", status); UnicodeString rules; rules.setTo(((RuleBasedCollator *)m_de_)->getRules()); UChar extrarules[128]; u_unescape(EXTRACOLLATIONRULE, extrarules, 128); rules.append(extrarules, u_strlen(extrarules)); delete m_de_; m_de_ = new RuleBasedCollator(rules, status); rules.setTo(((RuleBasedCollator *)m_es_)->getRules()); rules.append(extrarules, u_strlen(extrarules)); delete m_es_; m_es_ = new RuleBasedCollator(rules, status); m_en_wordbreaker_ = BreakIterator::createWordInstance( Locale::ENGLISH, status); m_en_characterbreaker_ = BreakIterator::createCharacterInstance( Locale::ENGLISH, status); } StringSearchTest::~StringSearchTest() { delete m_en_us_; delete m_fr_fr_; delete m_de_; delete m_es_; delete m_en_wordbreaker_; delete m_en_characterbreaker_; } // public methods ---------------------------------------------------------- void StringSearchTest::runIndexedTest(int32_t index, UBool exec, const char* &name, char* ) { 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; } switch (index) { CASE(0, TestOpenClose) CASE(1, TestInitialization) CASE(2, TestBasic) CASE(3, TestNormExact) CASE(4, TestStrength) CASE(5, TestBreakIterator) CASE(6, TestVariable) CASE(7, TestOverlap) CASE(8, TestCollator) CASE(9, TestPattern) CASE(10, TestText) CASE(11, TestCompositeBoundaries) CASE(12, TestGetSetOffset) CASE(13, TestGetSetAttribute) CASE(14, TestGetMatch) CASE(15, TestSetMatch) CASE(16, TestReset) CASE(17, TestSupplementary) CASE(18, TestContraction) CASE(19, TestIgnorable) CASE(20, TestCanonical) CASE(21, TestNormCanonical) CASE(22, TestStrengthCanonical) CASE(23, TestBreakIteratorCanonical) CASE(24, TestVariableCanonical) CASE(25, TestOverlapCanonical) CASE(26, TestCollatorCanonical) CASE(27, TestPatternCanonical) CASE(28, TestTextCanonical) CASE(29, TestCompositeBoundariesCanonical) CASE(30, TestGetSetOffsetCanonical) CASE(31, TestSupplementaryCanonical) CASE(32, TestContractionCanonical) CASE(33, TestSearchIterator) default: name = ""; break; } } // private methods ------------------------------------------------------ RuleBasedCollator * StringSearchTest::getCollator(const char *collator) { if (collator == NULL) { return m_en_us_; } if (strcmp(collator, "fr") == 0) { return m_fr_fr_; } else if (strcmp(collator, "de") == 0) { return m_de_; } else if (strcmp(collator, "es") == 0) { return m_es_; } else { return m_en_us_; } } BreakIterator * StringSearchTest::getBreakIterator(const char *breaker) { if (breaker == NULL) { return NULL; } if (strcmp(breaker, "wordbreaker") == 0) { return m_en_wordbreaker_; } else { return m_en_characterbreaker_; } } char * StringSearchTest::toCharString(const UnicodeString &text) { UChar unichars[512]; static char result[1024]; int count = 0; int index = 0; int length = text.length(); text.extract(0, text.length(), unichars, 0); for (; count < length; count ++) { UChar ch = unichars[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); } } result[index] = 0; return result; } Collator::ECollationStrength StringSearchTest::getECollationStrength( const UCollationStrength &strength) const { switch (strength) { case UCOL_PRIMARY : return Collator::PRIMARY; case UCOL_SECONDARY : return Collator::SECONDARY; case UCOL_TERTIARY : return Collator::TERTIARY; default : return Collator::IDENTICAL; } } UBool StringSearchTest::assertEqualWithStringSearch(StringSearch *strsrch, const SearchData *search) { int count = 0; UErrorCode status = U_ZERO_ERROR; UTextOffset matchindex = search->offset[count]; UnicodeString matchtext; if (strsrch->getMatchedStart() != USEARCH_DONE || strsrch->getMatchedLength() != 0) { errln("Error with the initialization of match start and length"); } // start of following matches while (U_SUCCESS(status) && matchindex >= 0) { int32_t matchlength = search->size[count]; strsrch->next(status); if (matchindex != strsrch->getMatchedStart() || matchlength != strsrch->getMatchedLength()) { char *str = toCharString(strsrch->getText()); errln("Text: %s", str); str = toCharString(strsrch->getPattern()); errln("Pattern: %s", str); errln("Error following match found at %d %d", strsrch->getMatchedStart(), strsrch->getMatchedLength()); return FALSE; } count ++; strsrch->getMatchedText(matchtext); if (U_FAILURE(status) || strsrch->getText().compareBetween(matchindex, matchindex + matchlength, matchtext, 0, matchtext.length())) { errln("Error getting following matched text"); } matchindex = search->offset[count]; } strsrch->next(status); 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 found at %d %d", strsrch->getMatchedStart(), strsrch->getMatchedLength()); return FALSE; } // start of preceding matches count = count == 0 ? 0 : count - 1; matchindex = search->offset[count]; while (U_SUCCESS(status) && matchindex >= 0) { int32_t matchlength = search->size[count]; strsrch->previous(status); if (matchindex != strsrch->getMatchedStart() || matchlength != strsrch->getMatchedLength()) { char *str = toCharString(strsrch->getText()); errln("Text: %s", str); str = toCharString(strsrch->getPattern()); errln("Pattern: %s", str); errln("Error following match found at %d %d", strsrch->getMatchedStart(), strsrch->getMatchedLength()); return FALSE; } strsrch->getMatchedText(matchtext); if (U_FAILURE(status) || strsrch->getText().compareBetween(matchindex, matchindex + matchlength, matchtext, 0, matchtext.length())) { errln("Error getting following matched text"); } matchindex = count > 0 ? search->offset[count - 1] : -1; count --; } strsrch->previous(status); 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 found at %d %d", strsrch->getMatchedStart(), strsrch->getMatchedLength()); return FALSE; } return TRUE; } UBool StringSearchTest::assertEqual(const SearchData *search) { UErrorCode status = U_ZERO_ERROR; Collator *collator = getCollator(search->collator); BreakIterator *breaker = getBreakIterator(search->breaker); StringSearch *strsrch; UChar temp[128]; u_unescape(search->text, temp, 128); UnicodeString text; text.setTo(temp); u_unescape(search->pattern, temp, 128); UnicodeString pattern; pattern.setTo(temp); if (breaker != NULL) { breaker->setText(text); } collator->setStrength(getECollationStrength(search->strength)); strsrch = new StringSearch(pattern, text, (RuleBasedCollator *)collator, breaker, status); if (U_FAILURE(status)) { errln("Error opening string search %s", u_errorName(status)); return FALSE; } if (!assertEqualWithStringSearch(strsrch, search)) { collator->setStrength(getECollationStrength(UCOL_TERTIARY)); delete strsrch; return FALSE; } collator->setStrength(getECollationStrength(UCOL_TERTIARY)); delete strsrch; return TRUE; } UBool StringSearchTest::assertCanonicalEqual(const SearchData *search) { UErrorCode status = U_ZERO_ERROR; Collator *collator = getCollator(search->collator); BreakIterator *breaker = getBreakIterator(search->breaker); StringSearch *strsrch; UChar temp[128]; u_unescape(search->text, temp, 128); UnicodeString text; text.setTo(temp); u_unescape(search->pattern, temp, 128); UnicodeString pattern; pattern.setTo(temp); if (breaker != NULL) { breaker->setText(text); } collator->setStrength(getECollationStrength(search->strength)); 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; } if (!assertEqualWithStringSearch(strsrch, search)) { collator->setStrength(getECollationStrength(UCOL_TERTIARY)); delete strsrch; return FALSE; } collator->setStrength(getECollationStrength(UCOL_TERTIARY)); delete strsrch; return TRUE; } UBool StringSearchTest::assertEqualWithAttribute(const SearchData *search, USearchAttributeValue canonical, USearchAttributeValue overlap) { UErrorCode status = U_ZERO_ERROR; Collator *collator = getCollator(search->collator); BreakIterator *breaker = getBreakIterator(search->breaker); StringSearch *strsrch; UChar temp[128]; u_unescape(search->text, temp, 128); UnicodeString text; text.setTo(temp); u_unescape(search->pattern, temp, 128); UnicodeString pattern; pattern.setTo(temp); if (breaker != NULL) { breaker->setText(text); } collator->setStrength(getECollationStrength(search->strength)); strsrch = new StringSearch(pattern, text, (RuleBasedCollator *)collator, breaker, status); strsrch->setAttribute(USEARCH_CANONICAL_MATCH, canonical, status); strsrch->setAttribute(USEARCH_OVERLAP, overlap, status); if (U_FAILURE(status)) { errln("Error opening string search %s", u_errorName(status)); return FALSE; } if (!assertEqualWithStringSearch(strsrch, search)) { collator->setStrength(getECollationStrength(UCOL_TERTIARY)); delete strsrch; return FALSE; } collator->setStrength(getECollationStrength(UCOL_TERTIARY)); delete strsrch; return TRUE; } void StringSearchTest::TestOpenClose() { UErrorCode status = U_ZERO_ERROR; StringSearch *result; BreakIterator *breakiter = m_en_wordbreaker_; UnicodeString pattern; UnicodeString text; UnicodeString temp("a"); StringCharacterIterator chariter(text); /* testing null arguments */ result = new StringSearch(pattern, text, NULL, NULL, status); if (U_SUCCESS(status)) { errln("Error: NULL arguments should produce an error"); } delete result; chariter.setText(text); status = U_ZERO_ERROR; result = new StringSearch(pattern, chariter, NULL, NULL, status); if (U_SUCCESS(status)) { errln("Error: NULL arguments should produce an error"); } delete result; text.append(0, 0x1); status = U_ZERO_ERROR; result = new StringSearch(pattern, text, NULL, NULL, status); if (U_SUCCESS(status)) { errln("Error: Empty pattern should produce an error"); } delete result; chariter.setText(text); status = U_ZERO_ERROR; result = new StringSearch(pattern, chariter, NULL, NULL, status); if (U_SUCCESS(status)) { errln("Error: Empty pattern should produce an error"); } delete result; text.remove(); pattern.append(temp); status = U_ZERO_ERROR; result = new StringSearch(pattern, text, NULL, NULL, status); if (U_SUCCESS(status)) { errln("Error: Empty text should produce an error"); } delete result; chariter.setText(text); status = U_ZERO_ERROR; result = new StringSearch(pattern, chariter, NULL, NULL, status); if (U_SUCCESS(status)) { errln("Error: Empty text should produce an error"); } delete result; text.append(temp); status = U_ZERO_ERROR; result = new StringSearch(pattern, text, NULL, NULL, status); if (U_SUCCESS(status)) { errln("Error: NULL arguments should produce an error"); } delete result; chariter.setText(text); status = U_ZERO_ERROR; result = new StringSearch(pattern, chariter, NULL, NULL, status); if (U_SUCCESS(status)) { errln("Error: NULL arguments should produce an error"); } delete result; status = U_ZERO_ERROR; result = new StringSearch(pattern, text, m_en_us_, NULL, status); if (U_FAILURE(status)) { errln("Error: NULL break iterator is valid for opening search"); } delete result; status = U_ZERO_ERROR; result = new StringSearch(pattern, chariter, m_en_us_, NULL, status); if (U_FAILURE(status)) { errln("Error: NULL break iterator is valid for opening search"); } delete result; status = U_ZERO_ERROR; result = new StringSearch(pattern, text, Locale::ENGLISH, NULL, status); if (U_FAILURE(status) || result == NULL) { errln("Error: NULL break iterator is valid for opening search"); } delete result; status = U_ZERO_ERROR; result = new StringSearch(pattern, chariter, Locale::ENGLISH, NULL, status); if (U_FAILURE(status)) { errln("Error: NULL break iterator is valid for opening search"); } delete result; status = U_ZERO_ERROR; result = new StringSearch(pattern, text, m_en_us_, breakiter, status); if (U_FAILURE(status)) { errln("Error: Break iterator is valid for opening search"); } delete result; status = U_ZERO_ERROR; result = new StringSearch(pattern, chariter, m_en_us_, NULL, status); if (U_FAILURE(status)) { errln("Error: Break iterator is valid for opening search"); } delete result; } void StringSearchTest::TestInitialization() { UErrorCode status = U_ZERO_ERROR; UnicodeString pattern; UnicodeString text; UnicodeString temp("a"); StringSearch *result; /* simple test on the pattern ce construction */ pattern.append(temp); pattern.append(temp); text.append(temp); text.append(temp); text.append(temp); result = new StringSearch(pattern, text, m_en_us_, NULL, status); if (U_FAILURE(status)) { errln("Error opening search %s", u_errorName(status)); } StringSearch *copy = new StringSearch(*result); if (*(copy->getCollator()) != *(result->getCollator()) || copy->getBreakIterator() != result->getBreakIterator() || copy->getMatchedLength() != result->getMatchedLength() || copy->getMatchedStart() != result->getMatchedStart() || copy->getOffset() != result->getOffset() || copy->getPattern() != result->getPattern() || copy->getText() != result->getText() || *(copy) != *(result)) { errln("Error copying StringSearch"); } delete copy; copy = (StringSearch *)result->safeClone(); if (*(copy->getCollator()) != *(result->getCollator()) || copy->getBreakIterator() != result->getBreakIterator() || copy->getMatchedLength() != result->getMatchedLength() || copy->getMatchedStart() != result->getMatchedStart() || copy->getOffset() != result->getOffset() || copy->getPattern() != result->getPattern() || copy->getText() != result->getText() || *(copy) != *(result)) { errln("Error copying StringSearch"); } delete result; /* testing if an extremely large pattern will fail the initialization */ for (int count = 0; count < 512; count ++) { pattern.append(temp); } result = new StringSearch(pattern, text, m_en_us_, NULL, status); if (*result != *result) { errln("Error: string search object expected to match itself"); } if (*result == *copy) { errln("Error: string search objects are not expected to match"); } *copy = *result; if (*(copy->getCollator()) != *(result->getCollator()) || copy->getBreakIterator() != result->getBreakIterator() || copy->getMatchedLength() != result->getMatchedLength() || copy->getMatchedStart() != result->getMatchedStart() || copy->getOffset() != result->getOffset() || copy->getPattern() != result->getPattern() || copy->getText() != result->getText() || *(copy) != *(result)) { errln("Error copying StringSearch"); } if (U_FAILURE(status)) { errln("Error opening search %s", u_errorName(status)); } delete result; delete copy; } void StringSearchTest::TestBasic() { int count = 0; while (BASIC[count].text != NULL) { //printf("count %d", count); if (!assertEqual(&BASIC[count])) { errln("Error at test number %d", count); } count ++; } } void StringSearchTest::TestNormExact() { int count = 0; UErrorCode status = U_ZERO_ERROR; m_en_us_->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status); if (U_FAILURE(status)) { errln("Error setting collation normalization %s", u_errorName(status)); } while (BASIC[count].text != NULL) { if (!assertEqual(&BASIC[count])) { errln("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); } count ++; } m_en_us_->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_OFF, status); count = 0; while (NONNORMEXACT[count].text != NULL) { if (!assertEqual(&NONNORMEXACT[count])) { errln("Error at test number %d", count); } count ++; } } void StringSearchTest::TestStrength() { int count = 0; while (STRENGTH[count].text != NULL) { if (!assertEqual(&STRENGTH[count])) { errln("Error at test number %d", count); } count ++; } } void StringSearchTest::TestBreakIterator() { UChar temp[128]; u_unescape(BREAKITERATOR[0].text, temp, 128); UnicodeString text; text.setTo(temp, u_strlen(temp)); u_unescape(BREAKITERATOR[0].pattern, temp, 128); UnicodeString pattern; pattern.setTo(temp, u_strlen(temp)); UErrorCode status = U_ZERO_ERROR; StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, status); if (U_FAILURE(status)) { errln("Error opening string search %s", u_errorName(status)); } strsrch->setBreakIterator(NULL, status); if (U_FAILURE(status) || strsrch->getBreakIterator() != NULL) { errln("Error usearch_getBreakIterator returned wrong object"); } strsrch->setBreakIterator(m_en_characterbreaker_, status); if (U_FAILURE(status) || strsrch->getBreakIterator() != m_en_characterbreaker_) { errln("Error usearch_getBreakIterator returned wrong object"); } strsrch->setBreakIterator(m_en_wordbreaker_, status); if (U_FAILURE(status) || strsrch->getBreakIterator() != m_en_wordbreaker_) { errln("Error usearch_getBreakIterator returned wrong object"); } delete strsrch; int count = 0; while (count < 4) { const SearchData *search = &(BREAKITERATOR[count]); RuleBasedCollator *collator = getCollator(search->collator); BreakIterator *breaker = getBreakIterator(search->breaker); StringSearch *strsrch; u_unescape(search->text, temp, 128); text.setTo(temp, u_strlen(temp)); u_unescape(search->pattern, temp, 128); pattern.setTo(temp, u_strlen(temp)); if (breaker != NULL) { breaker->setText(text); } collator->setStrength(getECollationStrength(search->strength)); strsrch = new StringSearch(pattern, text, collator, breaker, status); if (U_FAILURE(status) || strsrch->getBreakIterator() != breaker) { errln("Error setting break iterator"); if (strsrch != NULL) { delete strsrch; } } if (!assertEqualWithStringSearch(strsrch, search)) { collator->setStrength(getECollationStrength(UCOL_TERTIARY)); delete strsrch; } search = &(BREAKITERATOR[count + 1]); breaker = getBreakIterator(search->breaker); if (breaker != NULL) { breaker->setText(text); } strsrch->setBreakIterator(breaker, status); if (U_FAILURE(status) || strsrch->getBreakIterator() != breaker) { errln("Error setting break iterator"); delete strsrch; } strsrch->reset(); if (!assertEqualWithStringSearch(strsrch, search)) { errln("Error at test number %d", count); } delete strsrch; count += 2; } count = 0; while (BREAKITERATOR[count].text != NULL) { if (!assertEqual(&BREAKITERATOR[count])) { errln("Error at test number %d", count); } count ++; } } void StringSearchTest::TestVariable() { int count = 0; UErrorCode status = U_ZERO_ERROR; m_en_us_->setAttribute(UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, status); if (U_FAILURE(status)) { errln("Error setting collation alternate attribute %s", u_errorName(status)); } while (VARIABLE[count].text != NULL) { logln("variable %d", count); if (!assertEqual(&VARIABLE[count])) { errln("Error at test number %d", count); } count ++; } m_en_us_->setAttribute(UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE, status); } void StringSearchTest::TestOverlap() { int count = 0; while (OVERLAP[count].text != NULL) { if (!assertEqualWithAttribute(&OVERLAP[count], USEARCH_OFF, USEARCH_ON)) { errln("Error at overlap test number %d", count); } count ++; } count = 0; while (NONOVERLAP[count].text != NULL) { if (!assertEqual(&NONOVERLAP[count])) { errln("Error at non overlap test number %d", count); } count ++; } count = 0; while (count < 1) { const SearchData *search = &(OVERLAP[count]); UChar temp[128]; u_unescape(search->text, temp, 128); UnicodeString text; text.setTo(temp, u_strlen(temp)); u_unescape(search->pattern, temp, 128); UnicodeString pattern; pattern.setTo(temp, u_strlen(temp)); RuleBasedCollator *collator = getCollator(search->collator); UErrorCode status = U_ZERO_ERROR; StringSearch *strsrch = new StringSearch(pattern, text, collator, NULL, status); strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_ON, status); if (U_FAILURE(status) || strsrch->getAttribute(USEARCH_OVERLAP) != USEARCH_ON) { errln("Error setting overlap option"); } if (!assertEqualWithStringSearch(strsrch, search)) { delete strsrch; return; } search = &(NONOVERLAP[count]); strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_OFF, status); if (U_FAILURE(status) || strsrch->getAttribute(USEARCH_OVERLAP) != USEARCH_OFF) { errln("Error setting overlap option"); } strsrch->reset(); if (!assertEqualWithStringSearch(strsrch, search)) { delete strsrch; errln("Error at test number %d", count); } count ++; delete strsrch; } } void StringSearchTest::TestCollator() { // test collator that thinks "o" and "p" are the same thing UChar temp[128]; u_unescape(COLLATOR[0].text, temp, 128); UnicodeString text; text.setTo(temp, u_strlen(temp)); u_unescape(COLLATOR[0].pattern, temp, 128); UnicodeString pattern; pattern.setTo(temp, u_strlen(temp)); UErrorCode status = U_ZERO_ERROR; StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, status); if (U_FAILURE(status)) { errln("Error opening string search %s", u_errorName(status)); delete strsrch; return; } if (!assertEqualWithStringSearch(strsrch, &COLLATOR[0])) { delete strsrch; return; } u_unescape(TESTCOLLATORRULE, temp, 128); UnicodeString rules; rules.setTo(temp, u_strlen(temp)); RuleBasedCollator *tailored = new RuleBasedCollator(rules, status); tailored->setStrength(getECollationStrength(COLLATOR[1].strength)); if (U_FAILURE(status)) { errln("Error opening rule based collator %s", u_errorName(status)); delete strsrch; if (tailored != NULL) { delete tailored; } return; } strsrch->setCollator(tailored, status); if (U_FAILURE(status) || (*strsrch->getCollator()) != (*tailored)) { errln("Error setting rule based collator"); delete strsrch; if (tailored != NULL) { delete tailored; } } strsrch->reset(); if (!assertEqualWithStringSearch(strsrch, &COLLATOR[1])) { delete strsrch; if (tailored != NULL) { delete tailored; } return; } strsrch->setCollator(m_en_us_, status); strsrch->reset(); if (U_FAILURE(status) || (*strsrch->getCollator()) != (*m_en_us_)) { errln("Error setting rule based collator"); delete strsrch; if (tailored != NULL) { delete tailored; } } if (!assertEqualWithStringSearch(strsrch, &COLLATOR[0])) { errln("Error searching collator test"); } delete strsrch; if (tailored != NULL) { delete tailored; } } void StringSearchTest::TestPattern() { UChar temp[512]; u_unescape(PATTERN[0].text, temp, 512); UnicodeString text; text.setTo(temp, u_strlen(temp)); u_unescape(PATTERN[0].pattern, temp, 512); UnicodeString pattern; pattern.setTo(temp, u_strlen(temp)); m_en_us_->setStrength(getECollationStrength(PATTERN[0].strength)); UErrorCode status = U_ZERO_ERROR; StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, status); if (U_FAILURE(status)) { errln("Error opening string search %s", u_errorName(status)); m_en_us_->setStrength(getECollationStrength(UCOL_TERTIARY)); if (strsrch != NULL) { delete strsrch; } return; } if (strsrch->getPattern() != pattern) { errln("Error setting pattern"); } if (!assertEqualWithStringSearch(strsrch, &PATTERN[0])) { m_en_us_->setStrength(getECollationStrength(UCOL_TERTIARY)); if (strsrch != NULL) { delete strsrch; } return; } u_unescape(PATTERN[1].pattern, temp, 512); pattern.setTo(temp, u_strlen(temp)); strsrch->setPattern(pattern, status); if (pattern != strsrch->getPattern()) { errln("Error setting pattern"); m_en_us_->setStrength(getECollationStrength(UCOL_TERTIARY)); if (strsrch != NULL) { delete strsrch; } return; } strsrch->reset(); if (U_FAILURE(status)) { errln("Error setting pattern %s", u_errorName(status)); } if (!assertEqualWithStringSearch(strsrch, &PATTERN[1])) { m_en_us_->setStrength(getECollationStrength(UCOL_TERTIARY)); if (strsrch != NULL) { delete strsrch; } return; } u_unescape(PATTERN[0].pattern, temp, 512); pattern.setTo(temp, u_strlen(temp)); strsrch->setPattern(pattern, status); if (pattern != strsrch->getPattern()) { errln("Error setting pattern"); m_en_us_->setStrength(getECollationStrength(UCOL_TERTIARY)); if (strsrch != NULL) { delete strsrch; } return; } strsrch->reset(); if (U_FAILURE(status)) { errln("Error setting pattern %s", u_errorName(status)); } if (!assertEqualWithStringSearch(strsrch, &PATTERN[0])) { m_en_us_->setStrength(getECollationStrength(UCOL_TERTIARY)); if (strsrch != NULL) { delete strsrch; } return; } /* enormous pattern size to see if this crashes */ for (int templength = 0; templength != 512; templength ++) { temp[templength] = 0x61; } temp[511] = 0; pattern.setTo(temp, 511); strsrch->setPattern(pattern, status); if (U_FAILURE(status)) { errln("Error setting pattern with size 512, %s", u_errorName(status)); } m_en_us_->setStrength(getECollationStrength(UCOL_TERTIARY)); if (strsrch != NULL) { delete strsrch; } } void StringSearchTest::TestText() { UChar temp[128]; u_unescape(TEXT[0].text, temp, 128); UnicodeString text; text.setTo(temp, u_strlen(temp)); u_unescape(TEXT[0].pattern, temp, 128); UnicodeString pattern; pattern.setTo(temp, u_strlen(temp)); UErrorCode status = U_ZERO_ERROR; StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, status); if (U_FAILURE(status)) { errln("Error opening string search %s", u_errorName(status)); return; } if (text != strsrch->getText()) { errln("Error setting text"); } if (!assertEqualWithStringSearch(strsrch, &TEXT[0])) { delete strsrch; return; } u_unescape(TEXT[1].text, temp, 128); text.setTo(temp, u_strlen(temp)); strsrch->setText(text, status); if (text != strsrch->getText()) { errln("Error setting text"); delete strsrch; return; } if (U_FAILURE(status)) { errln("Error setting text %s", u_errorName(status)); } if (!assertEqualWithStringSearch(strsrch, &TEXT[1])) { delete strsrch; return; } u_unescape(TEXT[0].text, temp, 128); text.setTo(temp, u_strlen(temp)); StringCharacterIterator chariter(text); strsrch->setText(chariter, status); if (text != strsrch->getText()) { errln("Error setting text"); delete strsrch; return; } if (U_FAILURE(status)) { errln("Error setting pattern %s", u_errorName(status)); } if (!assertEqualWithStringSearch(strsrch, &TEXT[0])) { errln("Error searching within set text"); } delete strsrch; } void StringSearchTest::TestCompositeBoundaries() { int count = 0; while (COMPOSITEBOUNDARIES[count].text != NULL) { logln("composite %d", count); if (!assertEqual(&COMPOSITEBOUNDARIES[count])) { errln("Error at test number %d", count); } count ++; } } void StringSearchTest::TestGetSetOffset() { UErrorCode status = U_ZERO_ERROR; UnicodeString pattern("1234567890123456"); UnicodeString text("12345678901234567890123456789012"); StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, status); /* testing out of bounds error */ strsrch->setOffset(-1, status); if (U_SUCCESS(status)) { errln("Error expecting set offset error"); } strsrch->setOffset(128, status); if (U_SUCCESS(status)) { errln("Error expecting set offset error"); } int index = 0; while (BASIC[index].text != NULL) { UErrorCode status = U_ZERO_ERROR; SearchData search = BASIC[index ++]; UChar temp[128]; 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); int count = 0; UTextOffset matchindex = search.offset[count]; while (U_SUCCESS(status) && matchindex >= 0) { int32_t matchlength = search.size[count]; strsrch->next(status); if (matchindex != strsrch->getMatchedStart() || matchlength != strsrch->getMatchedLength()) { char *str = toCharString(strsrch->getText()); errln("Text: %s", str); str = toCharString(strsrch->getPattern()); errln("Pattern: %s", str); errln("Error match found at %d %d", strsrch->getMatchedStart(), strsrch->getMatchedLength()); return; } matchindex = search.offset[count + 1] == -1 ? -1 : search.offset[count + 2]; if (search.offset[count + 1] != -1) { strsrch->setOffset(search.offset[count + 1] + 1, status); if (strsrch->getOffset() != search.offset[count + 1] + 1) { errln("Error setting offset\n"); return; } } count += 2; } strsrch->next(status); if (strsrch->getMatchedStart() != USEARCH_DONE) { char *str = toCharString(strsrch->getText()); errln("Text: %s", str); str = toCharString(strsrch->getPattern()); errln("Pattern: %s", str); errln("Error match found at %d %d", strsrch->getMatchedStart(), strsrch->getMatchedLength()); return; } } delete strsrch; } void StringSearchTest::TestGetSetAttribute() { UErrorCode status = U_ZERO_ERROR; UnicodeString pattern("pattern"); UnicodeString text("text"); StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, status); if (U_FAILURE(status)) { errln("Error opening search %s", u_errorName(status)); return; } strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_DEFAULT, status); if (U_FAILURE(status) || strsrch->getAttribute(USEARCH_OVERLAP) != USEARCH_OFF) { errln("Error setting overlap to the default"); } strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_ON, status); if (U_FAILURE(status) || strsrch->getAttribute(USEARCH_OVERLAP) != USEARCH_ON) { errln("Error setting overlap true"); } strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_OFF, status); if (U_FAILURE(status) || strsrch->getAttribute(USEARCH_OVERLAP) != USEARCH_OFF) { errln("Error setting overlap false"); } strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_ATTRIBUTE_VALUE_COUNT, status); if (U_SUCCESS(status)) { errln("Error setting overlap to illegal value"); } status = U_ZERO_ERROR; strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_DEFAULT, status); if (U_FAILURE(status) || strsrch->getAttribute(USEARCH_CANONICAL_MATCH) != USEARCH_OFF) { errln("Error setting canonical match to the default"); } strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status); if (U_FAILURE(status) || strsrch->getAttribute(USEARCH_CANONICAL_MATCH) != USEARCH_ON) { errln("Error setting canonical match true"); } strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_OFF, status); if (U_FAILURE(status) || strsrch->getAttribute(USEARCH_CANONICAL_MATCH) != USEARCH_OFF) { errln("Error setting canonical match false"); } strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ATTRIBUTE_VALUE_COUNT, status); if (U_SUCCESS(status)) { errln("Error setting canonical match to illegal value"); } status = U_ZERO_ERROR; strsrch->setAttribute(USEARCH_ATTRIBUTE_COUNT, USEARCH_DEFAULT, status); if (U_SUCCESS(status)) { errln("Error setting illegal attribute success"); } delete strsrch; } void StringSearchTest::TestGetMatch() { UChar temp[128]; SearchData search = MATCH[0]; u_unescape(search.text, temp, 128); UnicodeString text; text.setTo(temp, u_strlen(temp)); u_unescape(search.pattern, temp, 128); UnicodeString pattern; pattern.setTo(temp, u_strlen(temp)); UErrorCode status = U_ZERO_ERROR; StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, status); if (U_FAILURE(status)) { errln("Error opening string search %s", u_errorName(status)); if (strsrch != NULL) { delete strsrch; } return; } int count = 0; UTextOffset matchindex = search.offset[count]; UnicodeString matchtext; while (U_SUCCESS(status) && matchindex >= 0) { int32_t matchlength = search.size[count]; strsrch->next(status); if (matchindex != strsrch->getMatchedStart() || matchlength != strsrch->getMatchedLength()) { char *str = toCharString(strsrch->getText()); errln("Text: %s", str); str = toCharString(strsrch->getPattern()); errln("Pattern: %s", str); errln("Error match found at %d %d", strsrch->getMatchedStart(), strsrch->getMatchedLength()); return; } count ++; status = U_ZERO_ERROR; strsrch->getMatchedText(matchtext); if (matchtext.length() != matchlength || U_FAILURE(status)){ errln("Error getting match text"); } matchindex = search.offset[count]; } status = U_ZERO_ERROR; strsrch->next(status); if (strsrch->getMatchedStart() != USEARCH_DONE || strsrch->getMatchedLength() != 0) { errln("Error end of match not found"); } status = U_ZERO_ERROR; strsrch->getMatchedText(matchtext); if (matchtext.length() != 0) { errln("Error getting null matches"); } delete strsrch; } void StringSearchTest::TestSetMatch() { int count = 0; while (MATCH[count].text != NULL) { SearchData search = MATCH[count]; UChar temp[128]; UErrorCode status = U_ZERO_ERROR; u_unescape(search.text, temp, 128); UnicodeString text; text.setTo(temp, u_strlen(temp)); u_unescape(search.pattern, temp, 128); UnicodeString pattern; pattern.setTo(temp, u_strlen(temp)); StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, status); if (U_FAILURE(status)) { errln("Error opening string search %s", u_errorName(status)); if (strsrch != NULL) { delete strsrch; } return; } int size = 0; while (search.offset[size] != -1) { size ++; } if (strsrch->first(status) != search.offset[0] || U_FAILURE(status)) { errln("Error getting first match"); } if (strsrch->last(status) != search.offset[size -1] || U_FAILURE(status)) { errln("Error getting last match"); } int index = 0; while (index < size) { if (index + 2 < size) { if (strsrch->following(search.offset[index + 2] - 1, status) != search.offset[index + 2] || U_FAILURE(status)) { errln("Error getting following match at index %d", search.offset[index + 2] - 1); } } if (index + 1 < size) { if (strsrch->preceding(search.offset[index + 1] + search.size[index + 1] + 1, status) != search.offset[index + 1] || U_FAILURE(status)) { errln("Error getting preceeding match at index %d", search.offset[index + 1] + 1); } } index += 2; } status = U_ZERO_ERROR; if (strsrch->following(text.length(), status) != USEARCH_DONE) { errln("Error expecting out of bounds match"); } if (strsrch->preceding(0, status) != USEARCH_DONE) { errln("Error expecting out of bounds match"); } count ++; delete strsrch; } } void StringSearchTest::TestReset() { UErrorCode status = U_ZERO_ERROR; UnicodeString text("fish fish"); UnicodeString pattern("s"); StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, status); if (U_FAILURE(status)) { errln("Error opening string search %s", u_errorName(status)); if (strsrch != NULL) { delete strsrch; } return; } strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_ON, status); strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status); strsrch->setOffset(9, status); if (U_FAILURE(status)) { errln("Error setting attributes and offsets"); } else { strsrch->reset(); if (strsrch->getAttribute(USEARCH_OVERLAP) != USEARCH_OFF || strsrch->getAttribute(USEARCH_CANONICAL_MATCH) != USEARCH_OFF || strsrch->getOffset() != 0 || strsrch->getMatchedLength() != 0 || strsrch->getMatchedStart() != USEARCH_DONE) { errln("Error resetting string search"); } strsrch->previous(status); if (strsrch->getMatchedStart() != 7 || strsrch->getMatchedLength() != 1) { errln("Error resetting string search\n"); } } delete strsrch; } void StringSearchTest::TestSupplementary() { int count = 0; while (SUPPLEMENTARY[count].text != NULL) { if (!assertEqual(&SUPPLEMENTARY[count])) { errln("Error at test number %d", count); } count ++; } } void StringSearchTest::TestContraction() { UChar temp[128]; UErrorCode status = U_ZERO_ERROR; u_unescape(CONTRACTIONRULE, temp, 128); UnicodeString rules; rules.setTo(temp, u_strlen(temp)); RuleBasedCollator *collator = new RuleBasedCollator(rules, getECollationStrength(UCOL_TERTIARY), Normalizer::DECOMP, status); if (U_FAILURE(status)) { errln("Error opening collator %s", u_errorName(status)); } UnicodeString text("text"); UnicodeString pattern("pattern"); StringSearch *strsrch = new StringSearch(pattern, text, collator, NULL, status); if (U_FAILURE(status)) { errln("Error opening string search %s", u_errorName(status)); } int count = 0; while (CONTRACTION[count].text != NULL) { u_unescape(CONTRACTION[count].text, temp, 128); text.setTo(temp, u_strlen(temp)); u_unescape(CONTRACTION[count].pattern, temp, 128); pattern.setTo(temp, u_strlen(temp)); strsrch->setText(text, status); strsrch->setPattern(pattern, status); if (!assertEqualWithStringSearch(strsrch, &CONTRACTION[count])) { errln("Error at test number %d", count); } count ++; } delete strsrch; delete collator; } void StringSearchTest::TestIgnorable() { UChar temp[128]; u_unescape(IGNORABLERULE, temp, 128); UnicodeString rules; rules.setTo(temp, u_strlen(temp)); UErrorCode status = U_ZERO_ERROR; int count = 0; RuleBasedCollator *collator = new RuleBasedCollator(rules, getECollationStrength(IGNORABLE[count].strength), Normalizer::DECOMP, status); if (U_FAILURE(status)) { errln("Error opening collator %s", u_errorName(status)); return; } UnicodeString pattern("pattern"); UnicodeString text("text"); StringSearch *strsrch = new StringSearch(pattern, text, collator, NULL, status); if (U_FAILURE(status)) { errln("Error opening string search %s", u_errorName(status)); delete collator; return; } while (IGNORABLE[count].text != NULL) { u_unescape(IGNORABLE[count].text, temp, 128); text.setTo(temp, u_strlen(temp)); u_unescape(IGNORABLE[count].pattern, temp, 128); pattern.setTo(temp, u_strlen(temp)); strsrch->setText(text, status); strsrch->setPattern(pattern, status); if (!assertEqualWithStringSearch(strsrch, &IGNORABLE[count])) { errln("Error at test number %d", count); } count ++; } delete strsrch; delete collator; } void StringSearchTest::TestCanonical() { int count = 0; while (BASICCANONICAL[count].text != NULL) { if (!assertCanonicalEqual(&BASICCANONICAL[count])) { errln("Error at test number %d", count); } count ++; } } void StringSearchTest::TestNormCanonical() { UErrorCode status = U_ZERO_ERROR; m_en_us_->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status); int count = 0; while (NORMCANONICAL[count].text != NULL) { if (!assertCanonicalEqual(&NORMCANONICAL[count])) { errln("Error at test number %d", count); } count ++; } m_en_us_->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_OFF, status); } void StringSearchTest::TestStrengthCanonical() { int count = 0; while (STRENGTHCANONICAL[count].text != NULL) { if (!assertCanonicalEqual(&STRENGTHCANONICAL[count])) { errln("Error at test number %d", count); } count ++; } } void StringSearchTest::TestBreakIteratorCanonical() { UErrorCode status = U_ZERO_ERROR; int count = 0; while (count < 4) { UChar temp[128]; const SearchData *search = &(BREAKITERATORCANONICAL[count]); u_unescape(search->text, temp, 128); UnicodeString text; text.setTo(temp, u_strlen(temp)); u_unescape(search->pattern, temp, 128); UnicodeString pattern; pattern.setTo(temp, u_strlen(temp)); RuleBasedCollator *collator = getCollator(search->collator); collator->setStrength(getECollationStrength(search->strength)); BreakIterator *breaker = getBreakIterator(search->breaker); StringSearch *strsrch = new StringSearch(pattern, text, collator, breaker, status); if (U_FAILURE(status)) { errln("Error creating string search data"); return; } strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status); if (U_FAILURE(status) || strsrch->getBreakIterator() != breaker) { errln("Error setting break iterator"); delete strsrch; return; } if (!assertEqualWithStringSearch(strsrch, search)) { collator->setStrength(getECollationStrength(UCOL_TERTIARY)); delete strsrch; return; } search = &(BREAKITERATOR[count + 1]); breaker = getBreakIterator(search->breaker); breaker->setText(strsrch->getText()); strsrch->setBreakIterator(breaker, status); if (U_FAILURE(status) || strsrch->getBreakIterator() != breaker) { errln("Error setting break iterator"); delete strsrch; return; } strsrch->reset(); strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status); if (!assertEqualWithStringSearch(strsrch, search)) { errln("Error at test number %d", count); return; } delete strsrch; count += 2; } count = 0; while (BREAKITERATORCANONICAL[count].text != NULL) { if (!assertEqual(&BREAKITERATORCANONICAL[count])) { errln("Error at test number %d", count); return; } count ++; } } void StringSearchTest::TestVariableCanonical() { int count = 0; UErrorCode status = U_ZERO_ERROR; m_en_us_->setAttribute(UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, status); if (U_FAILURE(status)) { errln("Error setting collation alternate attribute %s", u_errorName(status)); } while (VARIABLE[count].text != NULL) { logln("variable %d", count); if (!assertCanonicalEqual(&VARIABLE[count])) { errln("Error at test number %d", count); } count ++; } m_en_us_->setAttribute(UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE, status); } void StringSearchTest::TestOverlapCanonical() { int count = 0; while (OVERLAPCANONICAL[count].text != NULL) { if (!assertEqualWithAttribute(&OVERLAPCANONICAL[count], USEARCH_ON, USEARCH_ON)) { errln("Error at overlap test number %d", count); } count ++; } count = 0; while (NONOVERLAP[count].text != NULL) { if (!assertCanonicalEqual(&NONOVERLAPCANONICAL[count])) { errln("Error at non overlap test number %d", count); } count ++; } count = 0; while (count < 1) { UChar temp[128]; const SearchData *search = &(OVERLAPCANONICAL[count]); UErrorCode status = U_ZERO_ERROR; u_unescape(search->text, temp, 128); UnicodeString text; text.setTo(temp, u_strlen(temp)); u_unescape(search->pattern, temp, 128); UnicodeString pattern; pattern.setTo(temp, u_strlen(temp)); RuleBasedCollator *collator = getCollator(search->collator); StringSearch *strsrch = new StringSearch(pattern, text, collator, NULL, status); strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status); strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_ON, status); if (U_FAILURE(status) || strsrch->getAttribute(USEARCH_OVERLAP) != USEARCH_ON) { errln("Error setting overlap option"); } if (!assertEqualWithStringSearch(strsrch, search)) { delete strsrch; return; } search = &(NONOVERLAPCANONICAL[count]); strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_OFF, status); if (U_FAILURE(status) || strsrch->getAttribute(USEARCH_OVERLAP) != USEARCH_OFF) { errln("Error setting overlap option"); } strsrch->reset(); if (!assertEqualWithStringSearch(strsrch, search)) { delete strsrch; errln("Error at test number %d", count); } count ++; delete strsrch; } } void StringSearchTest::TestCollatorCanonical() { /* test collator that thinks "o" and "p" are the same thing */ UChar temp[128]; u_unescape(COLLATORCANONICAL[0].text, temp, 128); UnicodeString text; text.setTo(temp, u_strlen(temp)); u_unescape(COLLATORCANONICAL[0].pattern, temp, 128); UnicodeString pattern; pattern.setTo(temp, u_strlen(temp)); UErrorCode status = U_ZERO_ERROR; StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, status); strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status); if (U_FAILURE(status)) { errln("Error opening string search %s", u_errorName(status)); } if (!assertEqualWithStringSearch(strsrch, &COLLATORCANONICAL[0])) { delete strsrch; return; } u_unescape(TESTCOLLATORRULE, temp, 128); UnicodeString rules; rules.setTo(temp, u_strlen(temp)); RuleBasedCollator *tailored = new RuleBasedCollator(rules, getECollationStrength(COLLATORCANONICAL[1].strength), Normalizer::DECOMP, status); if (U_FAILURE(status)) { errln("Error opening rule based collator %s", u_errorName(status)); } strsrch->setCollator(tailored, status); if (U_FAILURE(status) || *(strsrch->getCollator()) != *tailored) { errln("Error setting rule based collator"); } strsrch->reset(); strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status); if (!assertEqualWithStringSearch(strsrch, &COLLATORCANONICAL[1])) { delete strsrch; if (tailored != NULL) { delete tailored; } } strsrch->setCollator(m_en_us_, status); strsrch->reset(); if (U_FAILURE(status) || *(strsrch->getCollator()) != *m_en_us_) { errln("Error setting rule based collator"); } if (!assertEqualWithStringSearch(strsrch, &COLLATORCANONICAL[0])) { } delete strsrch; if (tailored != NULL) { delete tailored; } } void StringSearchTest::TestPatternCanonical() { UChar temp[128]; u_unescape(PATTERNCANONICAL[0].text, temp, 128); UnicodeString text; text.setTo(temp, u_strlen(temp)); u_unescape(PATTERNCANONICAL[0].pattern, temp, 128); UnicodeString pattern; pattern.setTo(temp, u_strlen(temp)); m_en_us_->setStrength( getECollationStrength(PATTERNCANONICAL[0].strength)); UErrorCode status = U_ZERO_ERROR; StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, status); strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status); if (U_FAILURE(status)) { errln("Error opening string search %s", u_errorName(status)); goto ENDTESTPATTERN; } if (pattern != strsrch->getPattern()) { errln("Error setting pattern"); } if (!assertEqualWithStringSearch(strsrch, &PATTERNCANONICAL[0])) { goto ENDTESTPATTERN; } u_unescape(PATTERNCANONICAL[1].pattern, temp, 128); pattern.setTo(temp, u_strlen(temp)); strsrch->setPattern(pattern, status); if (pattern != strsrch->getPattern()) { errln("Error setting pattern"); goto ENDTESTPATTERN; } strsrch->reset(); strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status); if (U_FAILURE(status)) { errln("Error setting pattern %s", u_errorName(status)); } if (!assertEqualWithStringSearch(strsrch, &PATTERNCANONICAL[1])) { goto ENDTESTPATTERN; } u_unescape(PATTERNCANONICAL[0].pattern, temp, 128); pattern.setTo(temp, u_strlen(temp)); strsrch->setPattern(pattern, status); if (pattern != strsrch->getPattern()) { errln("Error setting pattern"); goto ENDTESTPATTERN; } strsrch->reset(); strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status); if (U_FAILURE(status)) { errln("Error setting pattern %s", u_errorName(status)); } if (!assertEqualWithStringSearch(strsrch, &PATTERNCANONICAL[0])) { goto ENDTESTPATTERN; } ENDTESTPATTERN: m_en_us_->setStrength(getECollationStrength(UCOL_TERTIARY)); if (strsrch != NULL) { delete strsrch; } } void StringSearchTest::TestTextCanonical() { UChar temp[128]; u_unescape(TEXTCANONICAL[0].text, temp, 128); UnicodeString text; text.setTo(temp, u_strlen(temp)); u_unescape(TEXTCANONICAL[0].pattern, temp, 128); UnicodeString pattern; pattern.setTo(temp, u_strlen(temp)); UErrorCode status = U_ZERO_ERROR; StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, status); strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status); if (U_FAILURE(status)) { errln("Error opening string search %s", u_errorName(status)); goto ENDTESTPATTERN; } if (text != strsrch->getText()) { errln("Error setting text"); } if (!assertEqualWithStringSearch(strsrch, &TEXTCANONICAL[0])) { goto ENDTESTPATTERN; } u_unescape(TEXTCANONICAL[1].text, temp, 128); text.setTo(temp, u_strlen(temp)); strsrch->setText(text, status); if (text != strsrch->getText()) { errln("Error setting text"); goto ENDTESTPATTERN; } if (U_FAILURE(status)) { errln("Error setting text %s", u_errorName(status)); } if (!assertEqualWithStringSearch(strsrch, &TEXTCANONICAL[1])) { goto ENDTESTPATTERN; } u_unescape(TEXTCANONICAL[0].text, temp, 128); text.setTo(temp, u_strlen(temp)); strsrch->setText(text, status); if (text != strsrch->getText()) { errln("Error setting text"); goto ENDTESTPATTERN; } if (U_FAILURE(status)) { errln("Error setting pattern %s", u_errorName(status)); } if (!assertEqualWithStringSearch(strsrch, &TEXTCANONICAL[0])) { goto ENDTESTPATTERN; } ENDTESTPATTERN: if (strsrch != NULL) { delete strsrch; } } void StringSearchTest::TestCompositeBoundariesCanonical() { int count = 0; while (COMPOSITEBOUNDARIESCANONICAL[count].text != NULL) { logln("composite %d", count); if (!assertCanonicalEqual(&COMPOSITEBOUNDARIESCANONICAL[count])) { errln("Error at test number %d", count); } count ++; } } void StringSearchTest::TestGetSetOffsetCanonical() { UErrorCode status = U_ZERO_ERROR; UnicodeString text("text"); UnicodeString pattern("pattern"); StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, status); strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status); /* testing out of bounds error */ strsrch->setOffset(-1, status); if (U_SUCCESS(status)) { errln("Error expecting set offset error"); } strsrch->setOffset(128, status); if (U_SUCCESS(status)) { errln("Error expecting set offset error"); } int index = 0; UChar temp[128]; while (BASICCANONICAL[index].text != NULL) { SearchData search = BASICCANONICAL[index ++]; if (BASICCANONICAL[index].text == NULL) { /* skip the last one */ break; } u_unescape(search.text, temp, 128); text.setTo(temp, u_strlen(temp)); u_unescape(search.pattern, temp, 128); pattern.setTo(temp, u_strlen(temp)); UErrorCode status = U_ZERO_ERROR; strsrch->setText(text, status); strsrch->setPattern(pattern, status); int count = 0; UTextOffset matchindex = search.offset[count]; while (U_SUCCESS(status) && matchindex >= 0) { int32_t matchlength = search.size[count]; strsrch->next(status); if (matchindex != strsrch->getMatchedStart() || matchlength != strsrch->getMatchedLength()) { char *str = toCharString(strsrch->getText()); errln("Text: %s", str); str = toCharString(strsrch->getPattern()); errln("Pattern: %s", str); errln("Error match found at %d %d", strsrch->getMatchedStart(), strsrch->getMatchedLength()); return; } matchindex = search.offset[count + 1] == -1 ? -1 : search.offset[count + 2]; if (search.offset[count + 1] != -1) { strsrch->setOffset(search.offset[count + 1] + 1, status); if (strsrch->getOffset() != search.offset[count + 1] + 1) { errln("Error setting offset"); return; } } count += 2; } strsrch->next(status); if (strsrch->getMatchedStart() != USEARCH_DONE) { char *str = toCharString(strsrch->getText()); errln("Text: %s", str); str = toCharString(strsrch->getPattern()); errln("Pattern: %s", str); errln("Error match found at %d %d", strsrch->getMatchedStart(), strsrch->getMatchedLength()); return; } } delete strsrch; } void StringSearchTest::TestSupplementaryCanonical() { int count = 0; while (SUPPLEMENTARYCANONICAL[count].text != NULL) { if (!assertCanonicalEqual(&SUPPLEMENTARYCANONICAL[count])) { errln("Error at test number %d", count); } count ++; } } void StringSearchTest::TestContractionCanonical() { UChar temp[128]; u_unescape(CONTRACTIONRULE, temp, 128); UnicodeString rules; rules.setTo(temp, u_strlen(temp)); UErrorCode status = U_ZERO_ERROR; RuleBasedCollator *collator = new RuleBasedCollator(rules, getECollationStrength(UCOL_TERTIARY), Normalizer::DECOMP, status); if (U_FAILURE(status)) { errln("Error opening collator %s", u_errorName(status)); } UnicodeString text("text"); UnicodeString pattern("pattern"); StringSearch *strsrch = new StringSearch(pattern, text, collator, NULL, status); strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status); if (U_FAILURE(status)) { errln("Error opening string search %s", u_errorName(status)); } int count = 0; while (CONTRACTIONCANONICAL[count].text != NULL) { u_unescape(CONTRACTIONCANONICAL[count].text, temp, 128); text.setTo(temp, u_strlen(temp)); u_unescape(CONTRACTIONCANONICAL[count].pattern, temp, 128); pattern.setTo(temp, u_strlen(temp)); strsrch->setText(text, status); strsrch->setPattern(pattern, status); if (!assertEqualWithStringSearch(strsrch, &CONTRACTIONCANONICAL[count])) { errln("Error at test number %d", count); } count ++; } delete strsrch; delete collator; } class TempSearch : public SearchIterator { public: TempSearch(); TempSearch(TempSearch &search); ~TempSearch(); void setOffset(UTextOffset position, UErrorCode &status); UTextOffset getOffset() const; SearchIterator* safeClone() const; protected: UTextOffset handleNext(UTextOffset position, UErrorCode &status); UTextOffset handlePrev(UTextOffset position, UErrorCode &status); }; TempSearch::TempSearch() : SearchIterator() { } TempSearch::TempSearch(TempSearch &search) : SearchIterator(search) { } TempSearch::~TempSearch() { } void TempSearch::setOffset(UTextOffset /*position*/, UErrorCode &/*status*/) { } UTextOffset TempSearch::getOffset() const { return USEARCH_DONE; } SearchIterator * TempSearch::safeClone() const { return NULL; } UTextOffset TempSearch::handleNext(UTextOffset /*position*/, UErrorCode &/*status*/) { return USEARCH_DONE; } UTextOffset TempSearch::handlePrev(UTextOffset /*position*/, UErrorCode &/*status*/) { return USEARCH_DONE; } void StringSearchTest::TestSearchIterator() { TempSearch search; if (search.getBreakIterator() != NULL || search.getAttribute(USEARCH_OVERLAP) != USEARCH_OFF || search.getAttribute(USEARCH_CANONICAL_MATCH) != USEARCH_OFF || search.getMatchedStart() != USEARCH_DONE || search.getMatchedLength() != 0 || search.getText().length() != 0) { errln("Error subclassing SearchIterator, default constructor failed"); return; } if (search.getAttribute(USEARCH_ATTRIBUTE_COUNT) != USEARCH_DEFAULT) { errln("Error getting illegal attribute failed"); return; } UnicodeString text("abc"); StringCharacterIterator striter(text); UErrorCode status = U_ZERO_ERROR; search.setText(text, status); TempSearch search2; search2.setText(striter, status); if (U_FAILURE(status) || search != search2) { errln("Error setting text"); return; } if (search != search) { errln("Error: search object has to be equals to itself"); return; } TempSearch search3(search); if (search != search3) { errln("Error: search object has to be equals to its copy"); return; } search.setAttribute(USEARCH_OVERLAP, USEARCH_ON, status); if (U_FAILURE(status) || search.getAttribute(USEARCH_OVERLAP) != USEARCH_ON) { errln("Error setting overlap attribute"); } search.reset(); if (search.getAttribute(USEARCH_OVERLAP) != USEARCH_OFF) { errln("Error resetting search"); } }