diff options
Diffstat (limited to 'Build/source/libs/icu/icu-xetex/test/intltest/srchtest.cpp')
-rw-r--r-- | Build/source/libs/icu/icu-xetex/test/intltest/srchtest.cpp | 2350 |
1 files changed, 2350 insertions, 0 deletions
diff --git a/Build/source/libs/icu/icu-xetex/test/intltest/srchtest.cpp b/Build/source/libs/icu/icu-xetex/test/intltest/srchtest.cpp new file mode 100644 index 00000000000..cde9da4bdd3 --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/test/intltest/srchtest.cpp @@ -0,0 +1,2350 @@ +/* +***************************************************************************** +* Copyright (C) 2001-2006, International Business Machines orporation +* and others. All Rights Reserved. +****************************************************************************/ + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_COLLATION + +#include "srchtest.h" +#include "../cintltst/usrchdat.c" +#include "unicode/stsearch.h" +#include "unicode/ustring.h" +#include "unicode/schriter.h" +#include <string.h> +#include <stdio.h> + +// private definitions ----------------------------------------------------- + +#define CASE(id,test) \ + case id: \ + name = #test; \ + if (exec) { \ + logln(#test "---"); \ + logln((UnicodeString)""); \ + if(areBroken) { \ + errln(__FILE__ " cannot test - failed to create collator."); \ + } else { \ + test(); \ + } \ + } \ + break; + +// public contructors and destructors -------------------------------------- + +StringSearchTest::StringSearchTest() : + m_en_wordbreaker_(NULL), m_en_characterbreaker_(NULL) +{ + 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); + if(U_FAILURE(status)) { + delete m_en_us_; + delete m_fr_fr_; + delete m_de_; + delete m_es_; + m_en_us_ = 0; + m_fr_fr_ = 0; + m_de_ = 0; + m_es_ = 0; + errln("Collator creation failed with %s", u_errorName(status)); + return; + } + + + 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); + +#if !UCONFIG_NO_BREAK_ITERATION + m_en_wordbreaker_ = BreakIterator::createWordInstance( + Locale::getEnglish(), status); + m_en_characterbreaker_ = BreakIterator::createCharacterInstance( + Locale::getEnglish(), status); +#endif +} + +StringSearchTest::~StringSearchTest() +{ + delete m_en_us_; + delete m_fr_fr_; + delete m_de_; + delete m_es_; +#if !UCONFIG_NO_BREAK_ITERATION + delete m_en_wordbreaker_; + delete m_en_characterbreaker_; +#endif +} + +// public methods ---------------------------------------------------------- + +void StringSearchTest::runIndexedTest(int32_t index, UBool exec, + const char* &name, char* ) +{ + 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) { + areBroken = TRUE; + } + + switch (index) { + CASE(0, TestOpenClose) + CASE(1, TestInitialization) + CASE(2, TestBasic) + CASE(3, TestNormExact) + CASE(4, TestStrength) +#if UCONFIG_NO_BREAK_ITERATION + case 5: + name = "TestBreakIterator"; + break; +#else + CASE(5, TestBreakIterator) +#endif + 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) +#if UCONFIG_NO_BREAK_ITERATION + case 23: + name = "TestBreakIteratorCanonical"; + break; +#else + CASE(23, TestBreakIteratorCanonical) +#endif + 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, TestUClassID) + CASE(34, TestSubclass) + CASE(35, TestCoverage) + CASE(36, TestDiactricMatch) + 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 UCONFIG_NO_BREAK_ITERATION + return NULL; +#else + if (breaker == NULL) { + return NULL; + } + if (strcmp(breaker, "wordbreaker") == 0) { + return m_en_wordbreaker_; + } + else { + return m_en_characterbreaker_; + } +#endif +} + +char * StringSearchTest::toCharString(const UnicodeString &text) +{ + static char result[1024]; + int index = 0; + int count = 0; + int length = text.length(); + + for (; count < length; count ++) { + UChar ch = text[count]; + if (ch >= 0x20 && ch <= 0x7e) { + result[index ++] = (char)ch; + } + else { + sprintf(result+index, "\\u%04x", ch); + index += 6; /* \uxxxx */ + } + } + 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; + int32_t 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, *strsrch2; + UChar temp[128]; + +#if UCONFIG_NO_BREAK_ITERATION + if(search->breaker) { + return TRUE; /* skip test */ + } +#endif + u_unescape(search->text, temp, 128); + UnicodeString text; + text.setTo(temp); + u_unescape(search->pattern, temp, 128); + UnicodeString pattern; + pattern.setTo(temp); + +#if !UCONFIG_NO_BREAK_ITERATION + if (breaker != NULL) { + breaker->setText(text); + } +#endif + 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; + } + + + strsrch2 = strsrch->clone(); + if( strsrch2 == strsrch || *strsrch2 != *strsrch || + !assertEqualWithStringSearch(strsrch2, search) + ) { + errln("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; +} + +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]; + +#if UCONFIG_NO_BREAK_ITERATION + if(search->breaker) { + return TRUE; /* skip test */ + } +#endif + + u_unescape(search->text, temp, 128); + UnicodeString text; + text.setTo(temp); + u_unescape(search->pattern, temp, 128); + UnicodeString pattern; + pattern.setTo(temp); + +#if !UCONFIG_NO_BREAK_ITERATION + if (breaker != NULL) { + breaker->setText(text); + } +#endif + 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]; + + +#if UCONFIG_NO_BREAK_ITERATION + if(search->breaker) { + return TRUE; /* skip test */ + } +#endif + + u_unescape(search->text, temp, 128); + UnicodeString text; + text.setTo(temp); + u_unescape(search->pattern, temp, 128); + UnicodeString pattern; + pattern.setTo(temp); + +#if !UCONFIG_NO_BREAK_ITERATION + if (breaker != NULL) { + breaker->setText(text); + } +#endif + 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::getEnglish(), 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::getEnglish(), 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; + int count; + + /* 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 (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 ++; + } +} + +#if !UCONFIG_NO_BREAK_ITERATION + +void StringSearchTest::TestBreakIterator() +{ + UChar temp[128]; + u_unescape(BREAKITERATOREXACT[0].text, temp, 128); + UnicodeString text; + text.setTo(temp, u_strlen(temp)); + u_unescape(BREAKITERATOREXACT[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) { + // special purposes for tests numbers 0-3 + const SearchData *search = &(BREAKITERATOREXACT[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 = &(BREAKITERATOREXACT[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 (BREAKITERATOREXACT[count].text != NULL) { + if (!assertEqual(&BREAKITERATOREXACT[count])) { + errln("Error at test number %d", count); + } + count ++; + } +} + +#endif + +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]; + int templength; + 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 (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); + strsrch->getCollator()->setStrength(getECollationStrength( + search.strength)); + strsrch->reset(); + + int count = 0; + int32_t 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; + } + } + strsrch->getCollator()->setStrength(getECollationStrength( + UCOL_TERTIARY)); + 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; + int32_t 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), UCOL_ON, 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), + UCOL_ON, 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::TestDiactricMatch() +{ + 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 = &(DIACTRICMATCH[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 = &(DIACTRICMATCH[++count]); + delete strsrch; + } + +} + +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 ++; + } +} + +#if !UCONFIG_NO_BREAK_ITERATION + +void StringSearchTest::TestBreakIteratorCanonical() +{ + UErrorCode status = U_ZERO_ERROR; + int count = 0; + + while (count < 4) { + // special purposes for tests numbers 0-3 + 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 = &(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) { + 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 ++; + } +} + +#endif + +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), + UCOL_ON, 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; + int32_t 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), UCOL_ON, 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; +} + +void StringSearchTest::TestUClassID() +{ + char id = *((char *)StringSearch::getStaticClassID()); + if (id != 0) { + errln("Static class id for StringSearch should be 0"); + } + UErrorCode status = U_ZERO_ERROR; + UnicodeString text("text"); + UnicodeString pattern("pattern"); + StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, + status); + id = *((char *)strsrch->getDynamicClassID()); + if (id != 0) { + errln("Dynamic class id for StringSearch should be 0"); + } + delete strsrch; +} + +class TestSearch : public SearchIterator +{ +public: + TestSearch(const TestSearch &obj); + TestSearch(const UnicodeString &text, + BreakIterator *breakiter, + const UnicodeString &pattern); + ~TestSearch(); + + void setOffset(int32_t position, UErrorCode &status); + int32_t getOffset() const; + SearchIterator* safeClone() const; + + + /** + * ICU "poor man's RTTI", returns a UClassID for the actual class. + * + * @draft ICU 2.2 + */ + virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); } + + /** + * ICU "poor man's RTTI", returns a UClassID for this class. + * + * @draft ICU 2.2 + */ + static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; } + + UBool operator!=(const TestSearch &that) const; + + UnicodeString m_pattern_; + +protected: + int32_t handleNext(int32_t position, UErrorCode &status); + int32_t handlePrev(int32_t position, UErrorCode &status); + TestSearch & operator=(const TestSearch &that); + +private: + + /** + * The address of this static class variable serves as this class's ID + * for ICU "poor man's RTTI". + */ + static const char fgClassID; + uint32_t m_offset_; +}; + +const char TestSearch::fgClassID=0; + +TestSearch::TestSearch(const TestSearch &obj) : SearchIterator(obj) +{ + m_offset_ = obj.m_offset_; + m_pattern_ = obj.m_pattern_; +} + +TestSearch::TestSearch(const UnicodeString &text, + BreakIterator *breakiter, + const UnicodeString &pattern) : SearchIterator() +{ + m_breakiterator_ = breakiter; + m_pattern_ = pattern; + m_text_ = text; + m_offset_ = 0; + m_pattern_ = pattern; +} + +TestSearch::~TestSearch() +{ +} + + +void TestSearch::setOffset(int32_t position, UErrorCode &status) +{ + if (position >= 0 && position <= m_text_.length()) { + m_offset_ = position; + } + else { + status = U_INDEX_OUTOFBOUNDS_ERROR; + } +} + +int32_t TestSearch::getOffset() const +{ + return m_offset_; +} + +SearchIterator * TestSearch::safeClone() const +{ + return new TestSearch(m_text_, m_breakiterator_, m_pattern_); +} + +UBool TestSearch::operator!=(const TestSearch &that) const +{ + if (SearchIterator::operator !=(that)) { + return FALSE; + } + return m_offset_ != that.m_offset_ || m_pattern_ != that.m_pattern_; +} + +int32_t TestSearch::handleNext(int32_t start, UErrorCode &status) +{ + if(U_SUCCESS(status)) { + int match = m_text_.indexOf(m_pattern_, start); + if (match < 0) { + m_offset_ = m_text_.length(); + setMatchStart(m_offset_); + setMatchLength(0); + return USEARCH_DONE; + } + setMatchStart(match); + m_offset_ = match; + setMatchLength(m_pattern_.length()); + return match; + } else { + return USEARCH_DONE; + } +} + +int32_t TestSearch::handlePrev(int32_t start, UErrorCode &status) +{ + if(U_SUCCESS(status)) { + int match = m_text_.lastIndexOf(m_pattern_, 0, start); + if (match < 0) { + m_offset_ = 0; + setMatchStart(m_offset_); + setMatchLength(0); + return USEARCH_DONE; + } + setMatchStart(match); + m_offset_ = match; + setMatchLength(m_pattern_.length()); + return match; + } else { + return USEARCH_DONE; + } +} + +TestSearch & TestSearch::operator=(const TestSearch &that) +{ + SearchIterator::operator=(that); + m_offset_ = that.m_offset_; + m_pattern_ = that.m_pattern_; + return *this; +} + +void StringSearchTest::TestSubclass() +{ + UnicodeString text("abc abcd abc"); + UnicodeString pattern("abc"); + TestSearch search(text, NULL, pattern); + TestSearch search2(search); + int expected[] = {0, 4, 9}; + UErrorCode status = U_ZERO_ERROR; + int i; + StringCharacterIterator chariter(text); + + search.setText(text, status); + if (search.getText() != search2.getText()) { + errln("Error setting text"); + } + + search.setText(chariter, status); + if (search.getText() != search2.getText()) { + errln("Error setting text"); + } + + search.reset(); + // comparing constructors + + for (i = 0; i < (int)(sizeof(expected) / sizeof(expected[0])); i ++) { + if (search.next(status) != expected[i]) { + errln("Error getting next match"); + } + if (search.getMatchedLength() != search.m_pattern_.length()) { + errln("Error getting next match length"); + } + } + 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 --) { + if (search.previous(status) != expected[i]) { + errln("Error getting previous match"); + } + if (search.getMatchedLength() != search.m_pattern_.length()) { + errln("Error getting previous match length"); + } + } + if (search.previous(status) != USEARCH_DONE) { + errln("Error should have reached the start of the iteration"); + } +} + +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 /* #if !UCONFIG_NO_COLLATION */ |