blob: ce6dc7125311f4f60ec350d56562f7d73cd25523 [file] [log] [blame]
/*
*****************************************************************************
* 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 <string.h>
// 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");
}
search2 = search3;
if (search2 != search3) {
errln("Error: search object has to be equals to its assignment copy");
return;
}
}