2 *****************************************************************************
3 * Copyright (C) 2001-2011, International Business Machines orporation
4 * and others. All Rights Reserved.
5 ****************************************************************************/
7 #include "unicode/utypes.h"
9 #if !UCONFIG_NO_COLLATION
12 #if !UCONFIG_NO_BREAK_ITERATION
13 #include "../cintltst/usrchdat.c"
15 #include "unicode/stsearch.h"
16 #include "unicode/ustring.h"
17 #include "unicode/schriter.h"
21 // private definitions -----------------------------------------------------
23 #define CASE(id,test) \
28 logln((UnicodeString)""); \
30 dataerrln(__FILE__ " cannot test - failed to create collator."); \
37 // public contructors and destructors --------------------------------------
39 StringSearchTest::StringSearchTest()
40 #if !UCONFIG_NO_BREAK_ITERATION
42 m_en_wordbreaker_(NULL
), m_en_characterbreaker_(NULL
)
45 #if !UCONFIG_NO_BREAK_ITERATION
46 UErrorCode status
= U_ZERO_ERROR
;
48 m_en_us_
= (RuleBasedCollator
*)Collator::createInstance("en_US", status
);
49 m_fr_fr_
= (RuleBasedCollator
*)Collator::createInstance("fr_FR", status
);
50 m_de_
= (RuleBasedCollator
*)Collator::createInstance("de_DE", status
);
51 m_es_
= (RuleBasedCollator
*)Collator::createInstance("es_ES", status
);
52 if(U_FAILURE(status
)) {
61 errln("Collator creation failed with %s", u_errorName(status
));
67 rules
.setTo(((RuleBasedCollator
*)m_de_
)->getRules());
68 UChar extrarules
[128];
69 u_unescape(EXTRACOLLATIONRULE
, extrarules
, 128);
70 rules
.append(extrarules
, u_strlen(extrarules
));
73 m_de_
= new RuleBasedCollator(rules
, status
);
75 rules
.setTo(((RuleBasedCollator
*)m_es_
)->getRules());
76 rules
.append(extrarules
, u_strlen(extrarules
));
80 m_es_
= new RuleBasedCollator(rules
, status
);
82 #if !UCONFIG_NO_BREAK_ITERATION
83 m_en_wordbreaker_
= BreakIterator::createWordInstance(
84 Locale::getEnglish(), status
);
85 m_en_characterbreaker_
= BreakIterator::createCharacterInstance(
86 Locale::getEnglish(), status
);
91 StringSearchTest::~StringSearchTest()
93 #if !UCONFIG_NO_BREAK_ITERATION
98 #if !UCONFIG_NO_BREAK_ITERATION
99 delete m_en_wordbreaker_
;
100 delete m_en_characterbreaker_
;
105 // public methods ----------------------------------------------------------
107 void StringSearchTest::runIndexedTest(int32_t index
, UBool exec
,
108 const char* &name
, char* )
110 #if !UCONFIG_NO_BREAK_ITERATION
111 UBool areBroken
= FALSE
;
112 if (m_en_us_
== NULL
&& m_fr_fr_
== NULL
&& m_de_
== NULL
&&
113 m_es_
== NULL
&& m_en_wordbreaker_
== NULL
&&
114 m_en_characterbreaker_
== NULL
&& exec
) {
119 #if !UCONFIG_NO_FILE_IO
120 CASE(0, TestOpenClose
)
122 CASE(1, TestInitialization
)
124 CASE(3, TestNormExact
)
125 CASE(4, TestStrength
)
126 #if UCONFIG_NO_BREAK_ITERATION
128 name
= "TestBreakIterator";
131 CASE(5, TestBreakIterator
)
133 CASE(6, TestVariable
)
135 CASE(8, TestCollator
)
138 CASE(11, TestCompositeBoundaries
)
139 CASE(12, TestGetSetOffset
)
140 CASE(13, TestGetSetAttribute
)
141 CASE(14, TestGetMatch
)
142 CASE(15, TestSetMatch
)
144 CASE(17, TestSupplementary
)
145 CASE(18, TestContraction
)
146 CASE(19, TestIgnorable
)
147 CASE(20, TestCanonical
)
148 CASE(21, TestNormCanonical
)
149 CASE(22, TestStrengthCanonical
)
150 #if UCONFIG_NO_BREAK_ITERATION
152 name
= "TestBreakIteratorCanonical";
155 CASE(23, TestBreakIteratorCanonical
)
157 CASE(24, TestVariableCanonical
)
158 CASE(25, TestOverlapCanonical
)
159 CASE(26, TestCollatorCanonical
)
160 CASE(27, TestPatternCanonical
)
161 CASE(28, TestTextCanonical
)
162 CASE(29, TestCompositeBoundariesCanonical
)
163 CASE(30, TestGetSetOffsetCanonical
)
164 CASE(31, TestSupplementaryCanonical
)
165 CASE(32, TestContractionCanonical
)
166 CASE(33, TestUClassID
)
167 CASE(34, TestSubclass
)
168 CASE(35, TestCoverage
)
169 CASE(36, TestDiacriticMatch
)
170 default: name
= ""; break;
177 #if !UCONFIG_NO_BREAK_ITERATION
178 // private methods ------------------------------------------------------
180 RuleBasedCollator
* StringSearchTest::getCollator(const char *collator
)
182 if (collator
== NULL
) {
185 if (strcmp(collator
, "fr") == 0) {
188 else if (strcmp(collator
, "de") == 0) {
191 else if (strcmp(collator
, "es") == 0) {
199 BreakIterator
* StringSearchTest::getBreakIterator(const char *breaker
)
201 #if UCONFIG_NO_BREAK_ITERATION
204 if (breaker
== NULL
) {
207 if (strcmp(breaker
, "wordbreaker") == 0) {
208 return m_en_wordbreaker_
;
211 return m_en_characterbreaker_
;
216 char * StringSearchTest::toCharString(const UnicodeString
&text
)
218 static char result
[1024];
221 int length
= text
.length();
223 for (; count
< length
; count
++) {
224 UChar ch
= text
[count
];
225 if (ch
>= 0x20 && ch
<= 0x7e) {
226 result
[index
++] = (char)ch
;
229 sprintf(result
+index
, "\\u%04x", ch
);
230 index
+= 6; /* \uxxxx */
238 Collator::ECollationStrength
StringSearchTest::getECollationStrength(
239 const UCollationStrength
&strength
) const
244 return Collator::PRIMARY
;
245 case UCOL_SECONDARY
:
246 return Collator::SECONDARY
;
248 return Collator::TERTIARY
;
250 return Collator::IDENTICAL
;
254 UBool
StringSearchTest::assertEqualWithStringSearch(StringSearch
*strsrch
,
255 const SearchData
*search
)
258 UErrorCode status
= U_ZERO_ERROR
;
259 int32_t matchindex
= search
->offset
[count
];
260 UnicodeString matchtext
;
263 strsrch
->setAttribute(USEARCH_ELEMENT_COMPARISON
, search
->elemCompare
, status
);
264 if (U_FAILURE(status
)) {
265 errln("Error setting USEARCH_ELEMENT_COMPARISON attribute %s", u_errorName(status
));
269 if (strsrch
->getMatchedStart() != USEARCH_DONE
||
270 strsrch
->getMatchedLength() != 0) {
271 errln("Error with the initialization of match start and length");
274 // start of next matches
275 while (U_SUCCESS(status
) && matchindex
>= 0) {
276 matchlength
= search
->size
[count
];
277 strsrch
->next(status
);
278 if (matchindex
!= strsrch
->getMatchedStart() ||
279 matchlength
!= strsrch
->getMatchedLength()) {
280 char *str
= toCharString(strsrch
->getText());
281 errln("Text: %s", str
);
282 str
= toCharString(strsrch
->getPattern());
283 errln("Pattern: %s", str
);
284 errln("Error next match found at %d (len:%d); expected %d (len:%d)",
285 strsrch
->getMatchedStart(), strsrch
->getMatchedLength(),
286 matchindex
, matchlength
);
291 strsrch
->getMatchedText(matchtext
);
293 if (U_FAILURE(status
) ||
294 strsrch
->getText().compareBetween(matchindex
,
295 matchindex
+ matchlength
,
297 matchtext
.length())) {
298 errln("Error getting next matched text");
301 matchindex
= search
->offset
[count
];
303 strsrch
->next(status
);
304 if (strsrch
->getMatchedStart() != USEARCH_DONE
||
305 strsrch
->getMatchedLength() != 0) {
306 char *str
= toCharString(strsrch
->getText());
307 errln("Text: %s", str
);
308 str
= toCharString(strsrch
->getPattern());
309 errln("Pattern: %s", str
);
310 errln("Error next match found at %d (len:%d); expected <NO MATCH>",
311 strsrch
->getMatchedStart(), strsrch
->getMatchedLength());
315 // start of previous matches
316 count
= count
== 0 ? 0 : count
- 1;
317 matchindex
= search
->offset
[count
];
318 while (U_SUCCESS(status
) && matchindex
>= 0) {
319 matchlength
= search
->size
[count
];
320 strsrch
->previous(status
);
321 if (matchindex
!= strsrch
->getMatchedStart() ||
322 matchlength
!= strsrch
->getMatchedLength()) {
323 char *str
= toCharString(strsrch
->getText());
324 errln("Text: %s", str
);
325 str
= toCharString(strsrch
->getPattern());
326 errln("Pattern: %s", str
);
327 errln("Error previous match found at %d (len:%d); expected %d (len:%d)",
328 strsrch
->getMatchedStart(), strsrch
->getMatchedLength(),
329 matchindex
, matchlength
);
333 strsrch
->getMatchedText(matchtext
);
335 if (U_FAILURE(status
) ||
336 strsrch
->getText().compareBetween(matchindex
,
337 matchindex
+ matchlength
,
339 matchtext
.length())) {
340 errln("Error getting previous matched text");
343 matchindex
= count
> 0 ? search
->offset
[count
- 1] : -1;
346 strsrch
->previous(status
);
347 if (strsrch
->getMatchedStart() != USEARCH_DONE
||
348 strsrch
->getMatchedLength() != 0) {
349 char *str
= toCharString(strsrch
->getText());
350 errln("Text: %s", str
);
351 str
= toCharString(strsrch
->getPattern());
352 errln("Pattern: %s", str
);
353 errln("Error previous match found at %d (len:%d); expected <NO MATCH>",
354 strsrch
->getMatchedStart(), strsrch
->getMatchedLength());
359 UBool isOverlap
= (strsrch
->getAttribute(USEARCH_OVERLAP
) == USEARCH_ON
);
361 // start of following matches
363 matchindex
= search
->offset
[count
];
367 strsrch
->following(nextStart
, status
);
369 if (matchindex
< 0) {
370 if (strsrch
->getMatchedStart() != USEARCH_DONE
||
371 strsrch
->getMatchedLength() != 0) {
372 char *str
= toCharString(strsrch
->getText());
373 errln("Text: %s", str
);
374 str
= toCharString(strsrch
->getPattern());
375 errln("Pattern: %s", str
);
376 errln("Error following match starting at %d (overlap:%d) found at %d (len:%d); expected <NO MATCH>",
377 nextStart
, isOverlap
,
378 strsrch
->getMatchedStart(), strsrch
->getMatchedLength());
385 matchlength
= search
->size
[count
];
386 if (strsrch
->getMatchedStart() != matchindex
387 || strsrch
->getMatchedLength() != matchlength
388 || U_FAILURE(status
)) {
389 char *str
= toCharString(strsrch
->getText());
390 errln("Text: %s\n", str
);
391 str
= toCharString(strsrch
->getPattern());
392 errln("Pattern: %s\n", str
);
393 errln("Error following match starting at %d (overlap: %d) found at %d (len:%d); expected %d (len:%d)\n",
394 nextStart
, isOverlap
,
395 strsrch
->getMatchedStart(), strsrch
->getMatchedLength(),
396 matchindex
, matchlength
);
400 if (isOverlap
|| strsrch
->getMatchedLength() == 0) {
401 nextStart
= strsrch
->getMatchedStart() + 1;
403 nextStart
= strsrch
->getMatchedStart() + strsrch
->getMatchedLength();
407 matchindex
= search
->offset
[count
];
410 // start preceding matches
411 count
= -1; // last non-negative offset index, could be -1 if no match
412 while (search
->offset
[count
+ 1] >= 0) {
415 nextStart
= strsrch
->getText().length();
418 strsrch
->preceding(nextStart
, status
);
421 if (strsrch
->getMatchedStart() != USEARCH_DONE
|| strsrch
->getMatchedLength() != 0) {
422 char *str
= toCharString(strsrch
->getText());
423 errln("Text: %s\n", str
);
424 str
= toCharString(strsrch
->getPattern());
425 errln("Pattern: %s\n", str
);
426 errln("Error preceding match starting at %d (overlap: %d) found at %d (len:%d); expected <NO MATCH>\n",
427 nextStart
, isOverlap
,
428 strsrch
->getMatchedStart(),
429 strsrch
->getMatchedLength());
436 matchindex
= search
->offset
[count
];
437 matchlength
= search
->size
[count
];
438 if (strsrch
->getMatchedStart() != matchindex
439 || strsrch
->getMatchedLength() != matchlength
440 || U_FAILURE(status
)) {
441 char *str
= toCharString(strsrch
->getText());
442 errln("Text: %s\n", str
);
443 str
= toCharString(strsrch
->getPattern());
444 errln("Pattern: %s\n", str
);
445 errln("Error preceding match starting at %d (overlap: %d) found at %d (len:%d); expected %d (len:%d)\n",
446 nextStart
, isOverlap
,
447 strsrch
->getMatchedStart(), strsrch
->getMatchedLength(),
448 matchindex
, matchlength
);
452 nextStart
= matchindex
;
456 strsrch
->setAttribute(USEARCH_ELEMENT_COMPARISON
, USEARCH_STANDARD_ELEMENT_COMPARISON
, status
);
460 UBool
StringSearchTest::assertEqual(const SearchData
*search
)
462 UErrorCode status
= U_ZERO_ERROR
;
464 Collator
*collator
= getCollator(search
->collator
);
465 BreakIterator
*breaker
= getBreakIterator(search
->breaker
);
466 StringSearch
*strsrch
, *strsrch2
;
469 #if UCONFIG_NO_BREAK_ITERATION
470 if(search
->breaker
) {
471 return TRUE
; /* skip test */
474 u_unescape(search
->text
, temp
, 128);
477 u_unescape(search
->pattern
, temp
, 128);
478 UnicodeString pattern
;
481 #if !UCONFIG_NO_BREAK_ITERATION
482 if (breaker
!= NULL
) {
483 breaker
->setText(text
);
486 collator
->setStrength(getECollationStrength(search
->strength
));
487 strsrch
= new StringSearch(pattern
, text
, (RuleBasedCollator
*)collator
,
489 if (U_FAILURE(status
)) {
490 errln("Error opening string search %s", u_errorName(status
));
494 if (!assertEqualWithStringSearch(strsrch
, search
)) {
495 collator
->setStrength(getECollationStrength(UCOL_TERTIARY
));
501 strsrch2
= strsrch
->clone();
502 if( strsrch2
== strsrch
|| *strsrch2
!= *strsrch
||
503 !assertEqualWithStringSearch(strsrch2
, search
)
505 infoln("failure with StringSearch.clone()");
506 collator
->setStrength(getECollationStrength(UCOL_TERTIARY
));
513 collator
->setStrength(getECollationStrength(UCOL_TERTIARY
));
518 UBool
StringSearchTest::assertCanonicalEqual(const SearchData
*search
)
520 UErrorCode status
= U_ZERO_ERROR
;
521 Collator
*collator
= getCollator(search
->collator
);
522 BreakIterator
*breaker
= getBreakIterator(search
->breaker
);
523 StringSearch
*strsrch
;
527 #if UCONFIG_NO_BREAK_ITERATION
528 if(search
->breaker
) {
529 return TRUE
; /* skip test */
533 u_unescape(search
->text
, temp
, 128);
536 u_unescape(search
->pattern
, temp
, 128);
537 UnicodeString pattern
;
540 #if !UCONFIG_NO_BREAK_ITERATION
541 if (breaker
!= NULL
) {
542 breaker
->setText(text
);
545 collator
->setStrength(getECollationStrength(search
->strength
));
546 collator
->setAttribute(UCOL_NORMALIZATION_MODE
, UCOL_ON
, status
);
547 strsrch
= new StringSearch(pattern
, text
, (RuleBasedCollator
*)collator
,
549 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
550 if (U_FAILURE(status
)) {
551 errln("Error opening string search %s", u_errorName(status
));
556 if (!assertEqualWithStringSearch(strsrch
, search
)) {
562 collator
->setStrength(getECollationStrength(UCOL_TERTIARY
));
563 collator
->setAttribute(UCOL_NORMALIZATION_MODE
, UCOL_OFF
, status
);
569 UBool
StringSearchTest::assertEqualWithAttribute(const SearchData
*search
,
570 USearchAttributeValue canonical
,
571 USearchAttributeValue overlap
)
573 UErrorCode status
= U_ZERO_ERROR
;
574 Collator
*collator
= getCollator(search
->collator
);
575 BreakIterator
*breaker
= getBreakIterator(search
->breaker
);
576 StringSearch
*strsrch
;
580 #if UCONFIG_NO_BREAK_ITERATION
581 if(search
->breaker
) {
582 return TRUE
; /* skip test */
586 u_unescape(search
->text
, temp
, 128);
589 u_unescape(search
->pattern
, temp
, 128);
590 UnicodeString pattern
;
593 #if !UCONFIG_NO_BREAK_ITERATION
594 if (breaker
!= NULL
) {
595 breaker
->setText(text
);
598 collator
->setStrength(getECollationStrength(search
->strength
));
599 strsrch
= new StringSearch(pattern
, text
, (RuleBasedCollator
*)collator
,
601 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, canonical
, status
);
602 strsrch
->setAttribute(USEARCH_OVERLAP
, overlap
, status
);
604 if (U_FAILURE(status
)) {
605 errln("Error opening string search %s", u_errorName(status
));
609 if (!assertEqualWithStringSearch(strsrch
, search
)) {
610 collator
->setStrength(getECollationStrength(UCOL_TERTIARY
));
614 collator
->setStrength(getECollationStrength(UCOL_TERTIARY
));
619 void StringSearchTest::TestOpenClose()
621 UErrorCode status
= U_ZERO_ERROR
;
622 StringSearch
*result
;
623 BreakIterator
*breakiter
= m_en_wordbreaker_
;
624 UnicodeString pattern
;
626 UnicodeString
temp("a");
627 StringCharacterIterator
chariter(text
);
629 /* testing null arguments */
630 result
= new StringSearch(pattern
, text
, NULL
, NULL
, status
);
631 if (U_SUCCESS(status
)) {
632 errln("Error: NULL arguments should produce an error");
636 chariter
.setText(text
);
637 status
= U_ZERO_ERROR
;
638 result
= new StringSearch(pattern
, chariter
, NULL
, NULL
, status
);
639 if (U_SUCCESS(status
)) {
640 errln("Error: NULL arguments should produce an error");
645 status
= U_ZERO_ERROR
;
646 result
= new StringSearch(pattern
, text
, NULL
, NULL
, status
);
647 if (U_SUCCESS(status
)) {
648 errln("Error: Empty pattern should produce an error");
652 chariter
.setText(text
);
653 status
= U_ZERO_ERROR
;
654 result
= new StringSearch(pattern
, chariter
, NULL
, NULL
, status
);
655 if (U_SUCCESS(status
)) {
656 errln("Error: Empty pattern should produce an error");
661 pattern
.append(temp
);
662 status
= U_ZERO_ERROR
;
663 result
= new StringSearch(pattern
, text
, NULL
, NULL
, status
);
664 if (U_SUCCESS(status
)) {
665 errln("Error: Empty text should produce an error");
669 chariter
.setText(text
);
670 status
= U_ZERO_ERROR
;
671 result
= new StringSearch(pattern
, chariter
, NULL
, NULL
, status
);
672 if (U_SUCCESS(status
)) {
673 errln("Error: Empty text should produce an error");
678 status
= U_ZERO_ERROR
;
679 result
= new StringSearch(pattern
, text
, NULL
, NULL
, status
);
680 if (U_SUCCESS(status
)) {
681 errln("Error: NULL arguments should produce an error");
685 chariter
.setText(text
);
686 status
= U_ZERO_ERROR
;
687 result
= new StringSearch(pattern
, chariter
, NULL
, NULL
, status
);
688 if (U_SUCCESS(status
)) {
689 errln("Error: NULL arguments should produce an error");
693 status
= U_ZERO_ERROR
;
694 result
= new StringSearch(pattern
, text
, m_en_us_
, NULL
, status
);
695 if (U_FAILURE(status
)) {
696 errln("Error: NULL break iterator is valid for opening search");
700 status
= U_ZERO_ERROR
;
701 result
= new StringSearch(pattern
, chariter
, m_en_us_
, NULL
, status
);
702 if (U_FAILURE(status
)) {
703 errln("Error: NULL break iterator is valid for opening search");
707 status
= U_ZERO_ERROR
;
708 result
= new StringSearch(pattern
, text
, Locale::getEnglish(), NULL
, status
);
709 if (U_FAILURE(status
) || result
== NULL
) {
710 errln("Error: NULL break iterator is valid for opening search");
714 status
= U_ZERO_ERROR
;
715 result
= new StringSearch(pattern
, chariter
, Locale::getEnglish(), NULL
, status
);
716 if (U_FAILURE(status
)) {
717 errln("Error: NULL break iterator is valid for opening search");
721 status
= U_ZERO_ERROR
;
722 result
= new StringSearch(pattern
, text
, m_en_us_
, breakiter
, status
);
723 if (U_FAILURE(status
)) {
724 errln("Error: Break iterator is valid for opening search");
728 status
= U_ZERO_ERROR
;
729 result
= new StringSearch(pattern
, chariter
, m_en_us_
, NULL
, status
);
730 if (U_FAILURE(status
)) {
731 errln("Error: Break iterator is valid for opening search");
736 void StringSearchTest::TestInitialization()
738 UErrorCode status
= U_ZERO_ERROR
;
739 UnicodeString pattern
;
741 UnicodeString
temp("a");
742 StringSearch
*result
;
745 /* simple test on the pattern ce construction */
746 pattern
.append(temp
);
747 pattern
.append(temp
);
751 result
= new StringSearch(pattern
, text
, m_en_us_
, NULL
, status
);
752 if (U_FAILURE(status
)) {
753 errln("Error opening search %s", u_errorName(status
));
755 StringSearch
*copy
= new StringSearch(*result
);
756 if (*(copy
->getCollator()) != *(result
->getCollator()) ||
757 copy
->getBreakIterator() != result
->getBreakIterator() ||
758 copy
->getMatchedLength() != result
->getMatchedLength() ||
759 copy
->getMatchedStart() != result
->getMatchedStart() ||
760 copy
->getOffset() != result
->getOffset() ||
761 copy
->getPattern() != result
->getPattern() ||
762 copy
->getText() != result
->getText() ||
763 *(copy
) != *(result
))
765 errln("Error copying StringSearch");
769 copy
= (StringSearch
*)result
->safeClone();
770 if (*(copy
->getCollator()) != *(result
->getCollator()) ||
771 copy
->getBreakIterator() != result
->getBreakIterator() ||
772 copy
->getMatchedLength() != result
->getMatchedLength() ||
773 copy
->getMatchedStart() != result
->getMatchedStart() ||
774 copy
->getOffset() != result
->getOffset() ||
775 copy
->getPattern() != result
->getPattern() ||
776 copy
->getText() != result
->getText() ||
777 *(copy
) != *(result
)) {
778 errln("Error copying StringSearch");
782 /* testing if an extremely large pattern will fail the initialization */
783 for (count
= 0; count
< 512; count
++) {
784 pattern
.append(temp
);
786 result
= new StringSearch(pattern
, text
, m_en_us_
, NULL
, status
);
787 if (*result
!= *result
) {
788 errln("Error: string search object expected to match itself");
790 if (*result
== *copy
) {
791 errln("Error: string search objects are not expected to match");
794 if (*(copy
->getCollator()) != *(result
->getCollator()) ||
795 copy
->getBreakIterator() != result
->getBreakIterator() ||
796 copy
->getMatchedLength() != result
->getMatchedLength() ||
797 copy
->getMatchedStart() != result
->getMatchedStart() ||
798 copy
->getOffset() != result
->getOffset() ||
799 copy
->getPattern() != result
->getPattern() ||
800 copy
->getText() != result
->getText() ||
801 *(copy
) != *(result
)) {
802 errln("Error copying StringSearch");
804 if (U_FAILURE(status
)) {
805 errln("Error opening search %s", u_errorName(status
));
811 void StringSearchTest::TestBasic()
814 while (BASIC
[count
].text
!= NULL
) {
815 //printf("count %d", count);
816 if (!assertEqual(&BASIC
[count
])) {
817 infoln("Error at test number %d", count
);
823 void StringSearchTest::TestNormExact()
826 UErrorCode status
= U_ZERO_ERROR
;
827 m_en_us_
->setAttribute(UCOL_NORMALIZATION_MODE
, UCOL_ON
, status
);
828 if (U_FAILURE(status
)) {
829 errln("Error setting collation normalization %s",
830 u_errorName(status
));
832 while (BASIC
[count
].text
!= NULL
) {
833 if (!assertEqual(&BASIC
[count
])) {
834 infoln("Error at test number %d", count
);
839 while (NORMEXACT
[count
].text
!= NULL
) {
840 if (!assertEqual(&NORMEXACT
[count
])) {
841 infoln("Error at test number %d", count
);
845 m_en_us_
->setAttribute(UCOL_NORMALIZATION_MODE
, UCOL_OFF
, status
);
847 while (NONNORMEXACT
[count
].text
!= NULL
) {
848 if (!assertEqual(&NONNORMEXACT
[count
])) {
849 infoln("Error at test number %d", count
);
855 void StringSearchTest::TestStrength()
858 while (STRENGTH
[count
].text
!= NULL
) {
859 if (!assertEqual(&STRENGTH
[count
])) {
860 infoln("Error at test number %d", count
);
866 #if !UCONFIG_NO_BREAK_ITERATION
868 void StringSearchTest::TestBreakIterator()
871 u_unescape(BREAKITERATOREXACT
[0].text
, temp
, 128);
873 text
.setTo(temp
, u_strlen(temp
));
874 u_unescape(BREAKITERATOREXACT
[0].pattern
, temp
, 128);
875 UnicodeString pattern
;
876 pattern
.setTo(temp
, u_strlen(temp
));
878 UErrorCode status
= U_ZERO_ERROR
;
879 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
, NULL
,
881 if (U_FAILURE(status
)) {
882 errln("Error opening string search %s", u_errorName(status
));
885 strsrch
->setBreakIterator(NULL
, status
);
886 if (U_FAILURE(status
) || strsrch
->getBreakIterator() != NULL
) {
887 errln("Error usearch_getBreakIterator returned wrong object");
890 strsrch
->setBreakIterator(m_en_characterbreaker_
, status
);
891 if (U_FAILURE(status
) ||
892 strsrch
->getBreakIterator() != m_en_characterbreaker_
) {
893 errln("Error usearch_getBreakIterator returned wrong object");
896 strsrch
->setBreakIterator(m_en_wordbreaker_
, status
);
897 if (U_FAILURE(status
) ||
898 strsrch
->getBreakIterator() != m_en_wordbreaker_
) {
899 errln("Error usearch_getBreakIterator returned wrong object");
906 // special purposes for tests numbers 0-3
907 const SearchData
*search
= &(BREAKITERATOREXACT
[count
]);
908 RuleBasedCollator
*collator
= getCollator(search
->collator
);
909 BreakIterator
*breaker
= getBreakIterator(search
->breaker
);
910 StringSearch
*strsrch
;
912 u_unescape(search
->text
, temp
, 128);
913 text
.setTo(temp
, u_strlen(temp
));
914 u_unescape(search
->pattern
, temp
, 128);
915 pattern
.setTo(temp
, u_strlen(temp
));
916 if (breaker
!= NULL
) {
917 breaker
->setText(text
);
919 collator
->setStrength(getECollationStrength(search
->strength
));
921 strsrch
= new StringSearch(pattern
, text
, collator
, breaker
, status
);
922 if (U_FAILURE(status
) ||
923 strsrch
->getBreakIterator() != breaker
) {
924 errln("Error setting break iterator");
925 if (strsrch
!= NULL
) {
929 if (!assertEqualWithStringSearch(strsrch
, search
)) {
930 collator
->setStrength(getECollationStrength(UCOL_TERTIARY
));
933 search
= &(BREAKITERATOREXACT
[count
+ 1]);
934 breaker
= getBreakIterator(search
->breaker
);
935 if (breaker
!= NULL
) {
936 breaker
->setText(text
);
938 strsrch
->setBreakIterator(breaker
, status
);
939 if (U_FAILURE(status
) ||
940 strsrch
->getBreakIterator() != breaker
) {
941 errln("Error setting break iterator");
945 if (!assertEqualWithStringSearch(strsrch
, search
)) {
946 infoln("Error at test number %d", count
);
952 while (BREAKITERATOREXACT
[count
].text
!= NULL
) {
953 if (!assertEqual(&BREAKITERATOREXACT
[count
])) {
954 infoln("Error at test number %d", count
);
962 void StringSearchTest::TestVariable()
965 UErrorCode status
= U_ZERO_ERROR
;
966 m_en_us_
->setAttribute(UCOL_ALTERNATE_HANDLING
, UCOL_SHIFTED
, status
);
967 if (U_FAILURE(status
)) {
968 errln("Error setting collation alternate attribute %s",
969 u_errorName(status
));
971 while (VARIABLE
[count
].text
!= NULL
) {
972 logln("variable %d", count
);
973 if (!assertEqual(&VARIABLE
[count
])) {
974 infoln("Error at test number %d", count
);
978 m_en_us_
->setAttribute(UCOL_ALTERNATE_HANDLING
, UCOL_NON_IGNORABLE
,
982 void StringSearchTest::TestOverlap()
985 while (OVERLAP
[count
].text
!= NULL
) {
986 if (!assertEqualWithAttribute(&OVERLAP
[count
], USEARCH_OFF
,
988 errln("Error at overlap test number %d", count
);
993 while (NONOVERLAP
[count
].text
!= NULL
) {
994 if (!assertEqual(&NONOVERLAP
[count
])) {
995 errln("Error at non overlap test number %d", count
);
1002 const SearchData
*search
= &(OVERLAP
[count
]);
1004 u_unescape(search
->text
, temp
, 128);
1006 text
.setTo(temp
, u_strlen(temp
));
1007 u_unescape(search
->pattern
, temp
, 128);
1008 UnicodeString pattern
;
1009 pattern
.setTo(temp
, u_strlen(temp
));
1011 RuleBasedCollator
*collator
= getCollator(search
->collator
);
1012 UErrorCode status
= U_ZERO_ERROR
;
1013 StringSearch
*strsrch
= new StringSearch(pattern
, text
,
1017 strsrch
->setAttribute(USEARCH_OVERLAP
, USEARCH_ON
, status
);
1018 if (U_FAILURE(status
) ||
1019 strsrch
->getAttribute(USEARCH_OVERLAP
) != USEARCH_ON
) {
1020 errln("Error setting overlap option");
1022 if (!assertEqualWithStringSearch(strsrch
, search
)) {
1027 search
= &(NONOVERLAP
[count
]);
1028 strsrch
->setAttribute(USEARCH_OVERLAP
, USEARCH_OFF
, status
);
1029 if (U_FAILURE(status
) ||
1030 strsrch
->getAttribute(USEARCH_OVERLAP
) != USEARCH_OFF
) {
1031 errln("Error setting overlap option");
1034 if (!assertEqualWithStringSearch(strsrch
, search
)) {
1036 errln("Error at test number %d", count
);
1044 void StringSearchTest::TestCollator()
1046 // test collator that thinks "o" and "p" are the same thing
1048 u_unescape(COLLATOR
[0].text
, temp
, 128);
1050 text
.setTo(temp
, u_strlen(temp
));
1051 u_unescape(COLLATOR
[0].pattern
, temp
, 128);
1052 UnicodeString pattern
;
1053 pattern
.setTo(temp
, u_strlen(temp
));
1055 UErrorCode status
= U_ZERO_ERROR
;
1056 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
, NULL
,
1058 if (U_FAILURE(status
)) {
1059 errln("Error opening string search %s", u_errorName(status
));
1063 if (!assertEqualWithStringSearch(strsrch
, &COLLATOR
[0])) {
1068 u_unescape(TESTCOLLATORRULE
, temp
, 128);
1069 UnicodeString rules
;
1070 rules
.setTo(temp
, u_strlen(temp
));
1071 RuleBasedCollator
*tailored
= new RuleBasedCollator(rules
, status
);
1072 tailored
->setStrength(getECollationStrength(COLLATOR
[1].strength
));
1074 if (U_FAILURE(status
)) {
1075 errln("Error opening rule based collator %s", u_errorName(status
));
1081 strsrch
->setCollator(tailored
, status
);
1082 if (U_FAILURE(status
) || (*strsrch
->getCollator()) != (*tailored
)) {
1083 errln("Error setting rule based collator");
1088 if (!assertEqualWithStringSearch(strsrch
, &COLLATOR
[1])) {
1094 strsrch
->setCollator(m_en_us_
, status
);
1096 if (U_FAILURE(status
) || (*strsrch
->getCollator()) != (*m_en_us_
)) {
1097 errln("Error setting rule based collator");
1101 if (!assertEqualWithStringSearch(strsrch
, &COLLATOR
[0])) {
1102 errln("Error searching collator test");
1108 void StringSearchTest::TestPattern()
1113 u_unescape(PATTERN
[0].text
, temp
, 512);
1115 text
.setTo(temp
, u_strlen(temp
));
1116 u_unescape(PATTERN
[0].pattern
, temp
, 512);
1117 UnicodeString pattern
;
1118 pattern
.setTo(temp
, u_strlen(temp
));
1120 m_en_us_
->setStrength(getECollationStrength(PATTERN
[0].strength
));
1121 UErrorCode status
= U_ZERO_ERROR
;
1122 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
, NULL
,
1125 if (U_FAILURE(status
)) {
1126 errln("Error opening string search %s", u_errorName(status
));
1127 m_en_us_
->setStrength(getECollationStrength(UCOL_TERTIARY
));
1128 if (strsrch
!= NULL
) {
1133 if (strsrch
->getPattern() != pattern
) {
1134 errln("Error setting pattern");
1136 if (!assertEqualWithStringSearch(strsrch
, &PATTERN
[0])) {
1137 m_en_us_
->setStrength(getECollationStrength(UCOL_TERTIARY
));
1138 if (strsrch
!= NULL
) {
1144 u_unescape(PATTERN
[1].pattern
, temp
, 512);
1145 pattern
.setTo(temp
, u_strlen(temp
));
1146 strsrch
->setPattern(pattern
, status
);
1147 if (pattern
!= strsrch
->getPattern()) {
1148 errln("Error setting pattern");
1149 m_en_us_
->setStrength(getECollationStrength(UCOL_TERTIARY
));
1150 if (strsrch
!= NULL
) {
1156 if (U_FAILURE(status
)) {
1157 errln("Error setting pattern %s", u_errorName(status
));
1159 if (!assertEqualWithStringSearch(strsrch
, &PATTERN
[1])) {
1160 m_en_us_
->setStrength(getECollationStrength(UCOL_TERTIARY
));
1161 if (strsrch
!= NULL
) {
1167 u_unescape(PATTERN
[0].pattern
, temp
, 512);
1168 pattern
.setTo(temp
, u_strlen(temp
));
1169 strsrch
->setPattern(pattern
, status
);
1170 if (pattern
!= strsrch
->getPattern()) {
1171 errln("Error setting pattern");
1172 m_en_us_
->setStrength(getECollationStrength(UCOL_TERTIARY
));
1173 if (strsrch
!= NULL
) {
1179 if (U_FAILURE(status
)) {
1180 errln("Error setting pattern %s", u_errorName(status
));
1182 if (!assertEqualWithStringSearch(strsrch
, &PATTERN
[0])) {
1183 m_en_us_
->setStrength(getECollationStrength(UCOL_TERTIARY
));
1184 if (strsrch
!= NULL
) {
1189 /* enormous pattern size to see if this crashes */
1190 for (templength
= 0; templength
!= 512; templength
++) {
1191 temp
[templength
] = 0x61;
1194 pattern
.setTo(temp
, 511);
1195 strsrch
->setPattern(pattern
, status
);
1196 if (U_FAILURE(status
)) {
1197 errln("Error setting pattern with size 512, %s", u_errorName(status
));
1199 m_en_us_
->setStrength(getECollationStrength(UCOL_TERTIARY
));
1200 if (strsrch
!= NULL
) {
1205 void StringSearchTest::TestText()
1208 u_unescape(TEXT
[0].text
, temp
, 128);
1210 text
.setTo(temp
, u_strlen(temp
));
1211 u_unescape(TEXT
[0].pattern
, temp
, 128);
1212 UnicodeString pattern
;
1213 pattern
.setTo(temp
, u_strlen(temp
));
1215 UErrorCode status
= U_ZERO_ERROR
;
1216 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
, NULL
,
1218 if (U_FAILURE(status
)) {
1219 errln("Error opening string search %s", u_errorName(status
));
1222 if (text
!= strsrch
->getText()) {
1223 errln("Error setting text");
1225 if (!assertEqualWithStringSearch(strsrch
, &TEXT
[0])) {
1230 u_unescape(TEXT
[1].text
, temp
, 128);
1231 text
.setTo(temp
, u_strlen(temp
));
1232 strsrch
->setText(text
, status
);
1233 if (text
!= strsrch
->getText()) {
1234 errln("Error setting text");
1238 if (U_FAILURE(status
)) {
1239 errln("Error setting text %s", u_errorName(status
));
1241 if (!assertEqualWithStringSearch(strsrch
, &TEXT
[1])) {
1246 u_unescape(TEXT
[0].text
, temp
, 128);
1247 text
.setTo(temp
, u_strlen(temp
));
1248 StringCharacterIterator
chariter(text
);
1249 strsrch
->setText(chariter
, status
);
1250 if (text
!= strsrch
->getText()) {
1251 errln("Error setting text");
1255 if (U_FAILURE(status
)) {
1256 errln("Error setting pattern %s", u_errorName(status
));
1258 if (!assertEqualWithStringSearch(strsrch
, &TEXT
[0])) {
1259 errln("Error searching within set text");
1264 void StringSearchTest::TestCompositeBoundaries()
1267 while (COMPOSITEBOUNDARIES
[count
].text
!= NULL
) {
1268 logln("composite %d", count
);
1269 if (!assertEqual(&COMPOSITEBOUNDARIES
[count
])) {
1270 errln("Error at test number %d", count
);
1276 void StringSearchTest::TestGetSetOffset()
1278 UErrorCode status
= U_ZERO_ERROR
;
1279 UnicodeString
pattern("1234567890123456");
1280 UnicodeString
text("12345678901234567890123456789012");
1281 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
,
1283 /* testing out of bounds error */
1284 strsrch
->setOffset(-1, status
);
1285 if (U_SUCCESS(status
)) {
1286 errln("Error expecting set offset error");
1288 strsrch
->setOffset(128, status
);
1289 if (U_SUCCESS(status
)) {
1290 errln("Error expecting set offset error");
1293 while (BASIC
[index
].text
!= NULL
) {
1294 UErrorCode status
= U_ZERO_ERROR
;
1295 SearchData search
= BASIC
[index
++];
1298 u_unescape(search
.text
, temp
, 128);
1299 text
.setTo(temp
, u_strlen(temp
));
1300 u_unescape(search
.pattern
, temp
, 128);
1301 pattern
.setTo(temp
, u_strlen(temp
));
1302 strsrch
->setText(text
, status
);
1303 strsrch
->setPattern(pattern
, status
);
1304 strsrch
->getCollator()->setStrength(getECollationStrength(
1309 int32_t matchindex
= search
.offset
[count
];
1310 while (U_SUCCESS(status
) && matchindex
>= 0) {
1311 int32_t matchlength
= search
.size
[count
];
1312 strsrch
->next(status
);
1313 if (matchindex
!= strsrch
->getMatchedStart() ||
1314 matchlength
!= strsrch
->getMatchedLength()) {
1315 char *str
= toCharString(strsrch
->getText());
1316 errln("Text: %s", str
);
1317 str
= toCharString(strsrch
->getPattern());
1318 errln("Pattern: %s", str
);
1319 errln("Error match found at %d %d",
1320 strsrch
->getMatchedStart(),
1321 strsrch
->getMatchedLength());
1324 matchindex
= search
.offset
[count
+ 1] == -1 ? -1 :
1325 search
.offset
[count
+ 2];
1326 if (search
.offset
[count
+ 1] != -1) {
1327 strsrch
->setOffset(search
.offset
[count
+ 1] + 1, status
);
1328 if (strsrch
->getOffset() != search
.offset
[count
+ 1] + 1) {
1329 errln("Error setting offset\n");
1336 strsrch
->next(status
);
1337 if (strsrch
->getMatchedStart() != USEARCH_DONE
) {
1338 char *str
= toCharString(strsrch
->getText());
1339 errln("Text: %s", str
);
1340 str
= toCharString(strsrch
->getPattern());
1341 errln("Pattern: %s", str
);
1342 errln("Error match found at %d %d",
1343 strsrch
->getMatchedStart(),
1344 strsrch
->getMatchedLength());
1348 strsrch
->getCollator()->setStrength(getECollationStrength(
1353 void StringSearchTest::TestGetSetAttribute()
1355 UErrorCode status
= U_ZERO_ERROR
;
1356 UnicodeString
pattern("pattern");
1357 UnicodeString
text("text");
1358 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
, NULL
,
1360 if (U_FAILURE(status
)) {
1361 errln("Error opening search %s", u_errorName(status
));
1365 strsrch
->setAttribute(USEARCH_OVERLAP
, USEARCH_DEFAULT
, status
);
1366 if (U_FAILURE(status
) ||
1367 strsrch
->getAttribute(USEARCH_OVERLAP
) != USEARCH_OFF
) {
1368 errln("Error setting overlap to the default");
1370 strsrch
->setAttribute(USEARCH_OVERLAP
, USEARCH_ON
, status
);
1371 if (U_FAILURE(status
) ||
1372 strsrch
->getAttribute(USEARCH_OVERLAP
) != USEARCH_ON
) {
1373 errln("Error setting overlap true");
1375 strsrch
->setAttribute(USEARCH_OVERLAP
, USEARCH_OFF
, status
);
1376 if (U_FAILURE(status
) ||
1377 strsrch
->getAttribute(USEARCH_OVERLAP
) != USEARCH_OFF
) {
1378 errln("Error setting overlap false");
1380 strsrch
->setAttribute(USEARCH_OVERLAP
, USEARCH_ATTRIBUTE_VALUE_COUNT
,
1382 if (U_SUCCESS(status
)) {
1383 errln("Error setting overlap to illegal value");
1385 status
= U_ZERO_ERROR
;
1386 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_DEFAULT
, status
);
1387 if (U_FAILURE(status
) ||
1388 strsrch
->getAttribute(USEARCH_CANONICAL_MATCH
) != USEARCH_OFF
) {
1389 errln("Error setting canonical match to the default");
1391 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
1392 if (U_FAILURE(status
) ||
1393 strsrch
->getAttribute(USEARCH_CANONICAL_MATCH
) != USEARCH_ON
) {
1394 errln("Error setting canonical match true");
1396 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_OFF
, status
);
1397 if (U_FAILURE(status
) ||
1398 strsrch
->getAttribute(USEARCH_CANONICAL_MATCH
) != USEARCH_OFF
) {
1399 errln("Error setting canonical match false");
1401 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
,
1402 USEARCH_ATTRIBUTE_VALUE_COUNT
, status
);
1403 if (U_SUCCESS(status
)) {
1404 errln("Error setting canonical match to illegal value");
1406 status
= U_ZERO_ERROR
;
1407 strsrch
->setAttribute(USEARCH_ATTRIBUTE_COUNT
, USEARCH_DEFAULT
, status
);
1408 if (U_SUCCESS(status
)) {
1409 errln("Error setting illegal attribute success");
1415 void StringSearchTest::TestGetMatch()
1418 SearchData search
= MATCH
[0];
1419 u_unescape(search
.text
, temp
, 128);
1421 text
.setTo(temp
, u_strlen(temp
));
1422 u_unescape(search
.pattern
, temp
, 128);
1423 UnicodeString pattern
;
1424 pattern
.setTo(temp
, u_strlen(temp
));
1426 UErrorCode status
= U_ZERO_ERROR
;
1427 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
, NULL
,
1429 if (U_FAILURE(status
)) {
1430 errln("Error opening string search %s", u_errorName(status
));
1431 if (strsrch
!= NULL
) {
1438 int32_t matchindex
= search
.offset
[count
];
1439 UnicodeString matchtext
;
1440 while (U_SUCCESS(status
) && matchindex
>= 0) {
1441 int32_t matchlength
= search
.size
[count
];
1442 strsrch
->next(status
);
1443 if (matchindex
!= strsrch
->getMatchedStart() ||
1444 matchlength
!= strsrch
->getMatchedLength()) {
1445 char *str
= toCharString(strsrch
->getText());
1446 errln("Text: %s", str
);
1447 str
= toCharString(strsrch
->getPattern());
1448 errln("Pattern: %s", str
);
1449 errln("Error match found at %d %d", strsrch
->getMatchedStart(),
1450 strsrch
->getMatchedLength());
1455 status
= U_ZERO_ERROR
;
1456 strsrch
->getMatchedText(matchtext
);
1457 if (matchtext
.length() != matchlength
|| U_FAILURE(status
)){
1458 errln("Error getting match text");
1460 matchindex
= search
.offset
[count
];
1462 status
= U_ZERO_ERROR
;
1463 strsrch
->next(status
);
1464 if (strsrch
->getMatchedStart() != USEARCH_DONE
||
1465 strsrch
->getMatchedLength() != 0) {
1466 errln("Error end of match not found");
1468 status
= U_ZERO_ERROR
;
1469 strsrch
->getMatchedText(matchtext
);
1470 if (matchtext
.length() != 0) {
1471 errln("Error getting null matches");
1476 void StringSearchTest::TestSetMatch()
1479 while (MATCH
[count
].text
!= NULL
) {
1480 SearchData search
= MATCH
[count
];
1482 UErrorCode status
= U_ZERO_ERROR
;
1483 u_unescape(search
.text
, temp
, 128);
1485 text
.setTo(temp
, u_strlen(temp
));
1486 u_unescape(search
.pattern
, temp
, 128);
1487 UnicodeString pattern
;
1488 pattern
.setTo(temp
, u_strlen(temp
));
1490 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
,
1492 if (U_FAILURE(status
)) {
1493 errln("Error opening string search %s", u_errorName(status
));
1494 if (strsrch
!= NULL
) {
1501 while (search
.offset
[size
] != -1) {
1505 if (strsrch
->first(status
) != search
.offset
[0] || U_FAILURE(status
)) {
1506 errln("Error getting first match");
1508 if (strsrch
->last(status
) != search
.offset
[size
-1] ||
1509 U_FAILURE(status
)) {
1510 errln("Error getting last match");
1514 while (index
< size
) {
1515 if (index
+ 2 < size
) {
1516 if (strsrch
->following(search
.offset
[index
+ 2] - 1, status
)
1517 != search
.offset
[index
+ 2] || U_FAILURE(status
)) {
1518 errln("Error getting following match at index %d",
1519 search
.offset
[index
+ 2] - 1);
1522 if (index
+ 1 < size
) {
1523 if (strsrch
->preceding(search
.offset
[index
+ 1] +
1524 search
.size
[index
+ 1] + 1,
1525 status
) != search
.offset
[index
+ 1] ||
1526 U_FAILURE(status
)) {
1527 errln("Error getting preceeding match at index %d",
1528 search
.offset
[index
+ 1] + 1);
1533 status
= U_ZERO_ERROR
;
1534 if (strsrch
->following(text
.length(), status
) != USEARCH_DONE
) {
1535 errln("Error expecting out of bounds match");
1537 if (strsrch
->preceding(0, status
) != USEARCH_DONE
) {
1538 errln("Error expecting out of bounds match");
1545 void StringSearchTest::TestReset()
1547 UErrorCode status
= U_ZERO_ERROR
;
1548 UnicodeString
text("fish fish");
1549 UnicodeString
pattern("s");
1550 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
, NULL
,
1552 if (U_FAILURE(status
)) {
1553 errln("Error opening string search %s", u_errorName(status
));
1554 if (strsrch
!= NULL
) {
1559 strsrch
->setAttribute(USEARCH_OVERLAP
, USEARCH_ON
, status
);
1560 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
1561 strsrch
->setOffset(9, status
);
1562 if (U_FAILURE(status
)) {
1563 errln("Error setting attributes and offsets");
1567 if (strsrch
->getAttribute(USEARCH_OVERLAP
) != USEARCH_OFF
||
1568 strsrch
->getAttribute(USEARCH_CANONICAL_MATCH
) != USEARCH_OFF
||
1569 strsrch
->getOffset() != 0 || strsrch
->getMatchedLength() != 0 ||
1570 strsrch
->getMatchedStart() != USEARCH_DONE
) {
1571 errln("Error resetting string search");
1573 strsrch
->previous(status
);
1574 if (strsrch
->getMatchedStart() != 7 ||
1575 strsrch
->getMatchedLength() != 1) {
1576 errln("Error resetting string search\n");
1582 void StringSearchTest::TestSupplementary()
1585 while (SUPPLEMENTARY
[count
].text
!= NULL
) {
1586 if (!assertEqual(&SUPPLEMENTARY
[count
])) {
1587 errln("Error at test number %d", count
);
1593 void StringSearchTest::TestContraction()
1596 UErrorCode status
= U_ZERO_ERROR
;
1598 u_unescape(CONTRACTIONRULE
, temp
, 128);
1599 UnicodeString rules
;
1600 rules
.setTo(temp
, u_strlen(temp
));
1601 RuleBasedCollator
*collator
= new RuleBasedCollator(rules
,
1602 getECollationStrength(UCOL_TERTIARY
), UCOL_ON
, status
);
1603 if (U_FAILURE(status
)) {
1604 errln("Error opening collator %s", u_errorName(status
));
1606 UnicodeString
text("text");
1607 UnicodeString
pattern("pattern");
1608 StringSearch
*strsrch
= new StringSearch(pattern
, text
, collator
, NULL
,
1610 if (U_FAILURE(status
)) {
1611 errln("Error opening string search %s", u_errorName(status
));
1615 while (CONTRACTION
[count
].text
!= NULL
) {
1616 u_unescape(CONTRACTION
[count
].text
, temp
, 128);
1617 text
.setTo(temp
, u_strlen(temp
));
1618 u_unescape(CONTRACTION
[count
].pattern
, temp
, 128);
1619 pattern
.setTo(temp
, u_strlen(temp
));
1620 strsrch
->setText(text
, status
);
1621 strsrch
->setPattern(pattern
, status
);
1622 if (!assertEqualWithStringSearch(strsrch
, &CONTRACTION
[count
])) {
1623 errln("Error at test number %d", count
);
1631 void StringSearchTest::TestIgnorable()
1634 u_unescape(IGNORABLERULE
, temp
, 128);
1635 UnicodeString rules
;
1636 rules
.setTo(temp
, u_strlen(temp
));
1637 UErrorCode status
= U_ZERO_ERROR
;
1639 RuleBasedCollator
*collator
= new RuleBasedCollator(rules
,
1640 getECollationStrength(IGNORABLE
[count
].strength
),
1642 if (U_FAILURE(status
)) {
1643 errln("Error opening collator %s", u_errorName(status
));
1646 UnicodeString
pattern("pattern");
1647 UnicodeString
text("text");
1648 StringSearch
*strsrch
= new StringSearch(pattern
, text
, collator
, NULL
,
1650 if (U_FAILURE(status
)) {
1651 errln("Error opening string search %s", u_errorName(status
));
1656 while (IGNORABLE
[count
].text
!= NULL
) {
1657 u_unescape(IGNORABLE
[count
].text
, temp
, 128);
1658 text
.setTo(temp
, u_strlen(temp
));
1659 u_unescape(IGNORABLE
[count
].pattern
, temp
, 128);
1660 pattern
.setTo(temp
, u_strlen(temp
));
1661 strsrch
->setText(text
, status
);
1662 strsrch
->setPattern(pattern
, status
);
1663 if (!assertEqualWithStringSearch(strsrch
, &IGNORABLE
[count
])) {
1664 errln("Error at test number %d", count
);
1672 void StringSearchTest::TestDiacriticMatch()
1675 UErrorCode status
= U_ZERO_ERROR
;
1677 RuleBasedCollator
* coll
= NULL
;
1678 StringSearch
*strsrch
= NULL
;
1680 UnicodeString
pattern("pattern");
1681 UnicodeString
text("text");
1683 const SearchData
*search
;
1685 search
= &(DIACRITICMATCH
[count
]);
1686 while (search
->text
!= NULL
) {
1687 coll
= getCollator(search
->collator
);
1688 coll
->setStrength(getECollationStrength(search
->strength
));
1689 strsrch
= new StringSearch(pattern
, text
, coll
, getBreakIterator(search
->breaker
), status
);
1690 if (U_FAILURE(status
)) {
1691 errln("Error opening string search %s", u_errorName(status
));
1694 u_unescape(search
->text
, temp
, 128);
1695 text
.setTo(temp
, u_strlen(temp
));
1696 u_unescape(search
->pattern
, temp
, 128);
1697 pattern
.setTo(temp
, u_strlen(temp
));
1698 strsrch
->setText(text
, status
);
1699 strsrch
->setPattern(pattern
, status
);
1700 if (!assertEqualWithStringSearch(strsrch
, search
)) {
1701 errln("Error at test number %d", count
);
1703 search
= &(DIACRITICMATCH
[++count
]);
1709 void StringSearchTest::TestCanonical()
1712 while (BASICCANONICAL
[count
].text
!= NULL
) {
1713 if (!assertCanonicalEqual(&BASICCANONICAL
[count
])) {
1714 errln("Error at test number %d", count
);
1720 void StringSearchTest::TestNormCanonical()
1722 UErrorCode status
= U_ZERO_ERROR
;
1723 m_en_us_
->setAttribute(UCOL_NORMALIZATION_MODE
, UCOL_ON
, status
);
1725 while (NORMCANONICAL
[count
].text
!= NULL
) {
1726 if (!assertCanonicalEqual(&NORMCANONICAL
[count
])) {
1727 errln("Error at test number %d", count
);
1731 m_en_us_
->setAttribute(UCOL_NORMALIZATION_MODE
, UCOL_OFF
, status
);
1734 void StringSearchTest::TestStrengthCanonical()
1737 while (STRENGTHCANONICAL
[count
].text
!= NULL
) {
1738 if (!assertCanonicalEqual(&STRENGTHCANONICAL
[count
])) {
1739 errln("Error at test number %d", count
);
1745 #if !UCONFIG_NO_BREAK_ITERATION
1747 void StringSearchTest::TestBreakIteratorCanonical()
1749 UErrorCode status
= U_ZERO_ERROR
;
1753 // special purposes for tests numbers 0-3
1755 const SearchData
*search
= &(BREAKITERATORCANONICAL
[count
]);
1757 u_unescape(search
->text
, temp
, 128);
1759 text
.setTo(temp
, u_strlen(temp
));
1760 u_unescape(search
->pattern
, temp
, 128);
1761 UnicodeString pattern
;
1762 pattern
.setTo(temp
, u_strlen(temp
));
1763 RuleBasedCollator
*collator
= getCollator(search
->collator
);
1764 collator
->setStrength(getECollationStrength(search
->strength
));
1766 BreakIterator
*breaker
= getBreakIterator(search
->breaker
);
1767 StringSearch
*strsrch
= new StringSearch(pattern
, text
, collator
,
1769 if (U_FAILURE(status
)) {
1770 errln("Error creating string search data");
1773 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
1774 if (U_FAILURE(status
) ||
1775 strsrch
->getBreakIterator() != breaker
) {
1776 errln("Error setting break iterator");
1780 if (!assertEqualWithStringSearch(strsrch
, search
)) {
1781 collator
->setStrength(getECollationStrength(UCOL_TERTIARY
));
1785 search
= &(BREAKITERATOREXACT
[count
+ 1]);
1786 breaker
= getBreakIterator(search
->breaker
);
1787 if (breaker
== NULL
) {
1788 errln("Error creating BreakIterator");
1791 breaker
->setText(strsrch
->getText());
1792 strsrch
->setBreakIterator(breaker
, status
);
1793 if (U_FAILURE(status
) || strsrch
->getBreakIterator() != breaker
) {
1794 errln("Error setting break iterator");
1799 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
1800 if (!assertEqualWithStringSearch(strsrch
, search
)) {
1801 errln("Error at test number %d", count
);
1808 while (BREAKITERATORCANONICAL
[count
].text
!= NULL
) {
1809 if (!assertEqual(&BREAKITERATORCANONICAL
[count
])) {
1810 errln("Error at test number %d", count
);
1819 void StringSearchTest::TestVariableCanonical()
1822 UErrorCode status
= U_ZERO_ERROR
;
1823 m_en_us_
->setAttribute(UCOL_ALTERNATE_HANDLING
, UCOL_SHIFTED
, status
);
1824 if (U_FAILURE(status
)) {
1825 errln("Error setting collation alternate attribute %s",
1826 u_errorName(status
));
1828 while (VARIABLE
[count
].text
!= NULL
) {
1829 logln("variable %d", count
);
1830 if (!assertCanonicalEqual(&VARIABLE
[count
])) {
1831 errln("Error at test number %d", count
);
1835 m_en_us_
->setAttribute(UCOL_ALTERNATE_HANDLING
, UCOL_NON_IGNORABLE
,
1839 void StringSearchTest::TestOverlapCanonical()
1842 while (OVERLAPCANONICAL
[count
].text
!= NULL
) {
1843 if (!assertEqualWithAttribute(&OVERLAPCANONICAL
[count
], USEARCH_ON
,
1845 errln("Error at overlap test number %d", count
);
1850 while (NONOVERLAP
[count
].text
!= NULL
) {
1851 if (!assertCanonicalEqual(&NONOVERLAPCANONICAL
[count
])) {
1852 errln("Error at non overlap test number %d", count
);
1860 const SearchData
*search
= &(OVERLAPCANONICAL
[count
]);
1861 UErrorCode status
= U_ZERO_ERROR
;
1863 u_unescape(search
->text
, temp
, 128);
1865 text
.setTo(temp
, u_strlen(temp
));
1866 u_unescape(search
->pattern
, temp
, 128);
1867 UnicodeString pattern
;
1868 pattern
.setTo(temp
, u_strlen(temp
));
1869 RuleBasedCollator
*collator
= getCollator(search
->collator
);
1870 StringSearch
*strsrch
= new StringSearch(pattern
, text
, collator
,
1872 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
1873 strsrch
->setAttribute(USEARCH_OVERLAP
, USEARCH_ON
, status
);
1874 if (U_FAILURE(status
) ||
1875 strsrch
->getAttribute(USEARCH_OVERLAP
) != USEARCH_ON
) {
1876 errln("Error setting overlap option");
1878 if (!assertEqualWithStringSearch(strsrch
, search
)) {
1882 search
= &(NONOVERLAPCANONICAL
[count
]);
1883 strsrch
->setAttribute(USEARCH_OVERLAP
, USEARCH_OFF
, status
);
1884 if (U_FAILURE(status
) ||
1885 strsrch
->getAttribute(USEARCH_OVERLAP
) != USEARCH_OFF
) {
1886 errln("Error setting overlap option");
1889 if (!assertEqualWithStringSearch(strsrch
, search
)) {
1891 errln("Error at test number %d", count
);
1899 void StringSearchTest::TestCollatorCanonical()
1901 /* test collator that thinks "o" and "p" are the same thing */
1903 u_unescape(COLLATORCANONICAL
[0].text
, temp
, 128);
1905 text
.setTo(temp
, u_strlen(temp
));
1906 u_unescape(COLLATORCANONICAL
[0].pattern
, temp
, 128);
1907 UnicodeString pattern
;
1908 pattern
.setTo(temp
, u_strlen(temp
));
1910 UErrorCode status
= U_ZERO_ERROR
;
1911 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
,
1913 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
1914 if (U_FAILURE(status
)) {
1915 errln("Error opening string search %s", u_errorName(status
));
1917 if (!assertEqualWithStringSearch(strsrch
, &COLLATORCANONICAL
[0])) {
1922 u_unescape(TESTCOLLATORRULE
, temp
, 128);
1923 UnicodeString rules
;
1924 rules
.setTo(temp
, u_strlen(temp
));
1925 RuleBasedCollator
*tailored
= new RuleBasedCollator(rules
,
1926 getECollationStrength(COLLATORCANONICAL
[1].strength
),
1929 if (U_FAILURE(status
)) {
1930 errln("Error opening rule based collator %s", u_errorName(status
));
1933 strsrch
->setCollator(tailored
, status
);
1934 if (U_FAILURE(status
) || *(strsrch
->getCollator()) != *tailored
) {
1935 errln("Error setting rule based collator");
1938 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
1939 if (!assertEqualWithStringSearch(strsrch
, &COLLATORCANONICAL
[1])) {
1941 if (tailored
!= NULL
) {
1948 strsrch
->setCollator(m_en_us_
, status
);
1950 if (U_FAILURE(status
) || *(strsrch
->getCollator()) != *m_en_us_
) {
1951 errln("Error setting rule based collator");
1953 if (!assertEqualWithStringSearch(strsrch
, &COLLATORCANONICAL
[0])) {
1956 if (tailored
!= NULL
) {
1961 void StringSearchTest::TestPatternCanonical()
1966 u_unescape(PATTERNCANONICAL
[0].text
, temp
, 128);
1968 text
.setTo(temp
, u_strlen(temp
));
1969 u_unescape(PATTERNCANONICAL
[0].pattern
, temp
, 128);
1970 UnicodeString pattern
;
1971 pattern
.setTo(temp
, u_strlen(temp
));
1973 m_en_us_
->setStrength(
1974 getECollationStrength(PATTERNCANONICAL
[0].strength
));
1976 UErrorCode status
= U_ZERO_ERROR
;
1977 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
, NULL
,
1979 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
1980 if (U_FAILURE(status
)) {
1981 errln("Error opening string search %s", u_errorName(status
));
1982 goto ENDTESTPATTERN
;
1984 if (pattern
!= strsrch
->getPattern()) {
1985 errln("Error setting pattern");
1987 if (!assertEqualWithStringSearch(strsrch
, &PATTERNCANONICAL
[0])) {
1988 goto ENDTESTPATTERN
;
1991 u_unescape(PATTERNCANONICAL
[1].pattern
, temp
, 128);
1992 pattern
.setTo(temp
, u_strlen(temp
));
1993 strsrch
->setPattern(pattern
, status
);
1994 if (pattern
!= strsrch
->getPattern()) {
1995 errln("Error setting pattern");
1996 goto ENDTESTPATTERN
;
1999 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
2000 if (U_FAILURE(status
)) {
2001 errln("Error setting pattern %s", u_errorName(status
));
2003 if (!assertEqualWithStringSearch(strsrch
, &PATTERNCANONICAL
[1])) {
2004 goto ENDTESTPATTERN
;
2007 u_unescape(PATTERNCANONICAL
[0].pattern
, temp
, 128);
2008 pattern
.setTo(temp
, u_strlen(temp
));
2009 strsrch
->setPattern(pattern
, status
);
2010 if (pattern
!= strsrch
->getPattern()) {
2011 errln("Error setting pattern");
2012 goto ENDTESTPATTERN
;
2015 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
2016 if (U_FAILURE(status
)) {
2017 errln("Error setting pattern %s", u_errorName(status
));
2019 if (!assertEqualWithStringSearch(strsrch
, &PATTERNCANONICAL
[0])) {
2020 goto ENDTESTPATTERN
;
2023 m_en_us_
->setStrength(getECollationStrength(UCOL_TERTIARY
));
2024 if (strsrch
!= NULL
) {
2029 void StringSearchTest::TestTextCanonical()
2032 u_unescape(TEXTCANONICAL
[0].text
, temp
, 128);
2034 text
.setTo(temp
, u_strlen(temp
));
2035 u_unescape(TEXTCANONICAL
[0].pattern
, temp
, 128);
2036 UnicodeString pattern
;
2037 pattern
.setTo(temp
, u_strlen(temp
));
2039 UErrorCode status
= U_ZERO_ERROR
;
2040 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
, NULL
,
2042 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
2044 if (U_FAILURE(status
)) {
2045 errln("Error opening string search %s", u_errorName(status
));
2046 goto ENDTESTPATTERN
;
2048 if (text
!= strsrch
->getText()) {
2049 errln("Error setting text");
2051 if (!assertEqualWithStringSearch(strsrch
, &TEXTCANONICAL
[0])) {
2052 goto ENDTESTPATTERN
;
2055 u_unescape(TEXTCANONICAL
[1].text
, temp
, 128);
2056 text
.setTo(temp
, u_strlen(temp
));
2057 strsrch
->setText(text
, status
);
2058 if (text
!= strsrch
->getText()) {
2059 errln("Error setting text");
2060 goto ENDTESTPATTERN
;
2062 if (U_FAILURE(status
)) {
2063 errln("Error setting text %s", u_errorName(status
));
2065 if (!assertEqualWithStringSearch(strsrch
, &TEXTCANONICAL
[1])) {
2066 goto ENDTESTPATTERN
;
2069 u_unescape(TEXTCANONICAL
[0].text
, temp
, 128);
2070 text
.setTo(temp
, u_strlen(temp
));
2071 strsrch
->setText(text
, status
);
2072 if (text
!= strsrch
->getText()) {
2073 errln("Error setting text");
2074 goto ENDTESTPATTERN
;
2076 if (U_FAILURE(status
)) {
2077 errln("Error setting pattern %s", u_errorName(status
));
2079 if (!assertEqualWithStringSearch(strsrch
, &TEXTCANONICAL
[0])) {
2080 goto ENDTESTPATTERN
;
2083 if (strsrch
!= NULL
) {
2088 void StringSearchTest::TestCompositeBoundariesCanonical()
2091 while (COMPOSITEBOUNDARIESCANONICAL
[count
].text
!= NULL
) {
2092 logln("composite %d", count
);
2093 if (!assertCanonicalEqual(&COMPOSITEBOUNDARIESCANONICAL
[count
])) {
2094 errln("Error at test number %d", count
);
2100 void StringSearchTest::TestGetSetOffsetCanonical()
2103 UErrorCode status
= U_ZERO_ERROR
;
2104 UnicodeString
text("text");
2105 UnicodeString
pattern("pattern");
2106 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
, NULL
,
2108 Collator
*collator
= strsrch
->getCollator();
2110 collator
->setAttribute(UCOL_NORMALIZATION_MODE
, UCOL_ON
, status
);
2112 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
2113 /* testing out of bounds error */
2114 strsrch
->setOffset(-1, status
);
2115 if (U_SUCCESS(status
)) {
2116 errln("Error expecting set offset error");
2118 strsrch
->setOffset(128, status
);
2119 if (U_SUCCESS(status
)) {
2120 errln("Error expecting set offset error");
2124 while (BASICCANONICAL
[index
].text
!= NULL
) {
2125 SearchData search
= BASICCANONICAL
[index
++];
2126 if (BASICCANONICAL
[index
].text
== NULL
) {
2127 /* skip the last one */
2131 u_unescape(search
.text
, temp
, 128);
2132 text
.setTo(temp
, u_strlen(temp
));
2133 u_unescape(search
.pattern
, temp
, 128);
2134 pattern
.setTo(temp
, u_strlen(temp
));
2136 UErrorCode status
= U_ZERO_ERROR
;
2137 strsrch
->setText(text
, status
);
2139 strsrch
->setPattern(pattern
, status
);
2142 int32_t matchindex
= search
.offset
[count
];
2143 while (U_SUCCESS(status
) && matchindex
>= 0) {
2144 int32_t matchlength
= search
.size
[count
];
2145 strsrch
->next(status
);
2146 if (matchindex
!= strsrch
->getMatchedStart() ||
2147 matchlength
!= strsrch
->getMatchedLength()) {
2148 char *str
= toCharString(strsrch
->getText());
2149 errln("Text: %s", str
);
2150 str
= toCharString(strsrch
->getPattern());
2151 errln("Pattern: %s", str
);
2152 errln("Error match found at %d %d",
2153 strsrch
->getMatchedStart(),
2154 strsrch
->getMatchedLength());
2157 matchindex
= search
.offset
[count
+ 1] == -1 ? -1 :
2158 search
.offset
[count
+ 2];
2159 if (search
.offset
[count
+ 1] != -1) {
2160 strsrch
->setOffset(search
.offset
[count
+ 1] + 1, status
);
2161 if (strsrch
->getOffset() != search
.offset
[count
+ 1] + 1) {
2162 errln("Error setting offset");
2169 strsrch
->next(status
);
2170 if (strsrch
->getMatchedStart() != USEARCH_DONE
) {
2171 char *str
= toCharString(strsrch
->getText());
2172 errln("Text: %s", str
);
2173 str
= toCharString(strsrch
->getPattern());
2174 errln("Pattern: %s", str
);
2175 errln("Error match found at %d %d", strsrch
->getMatchedStart(),
2176 strsrch
->getMatchedLength());
2182 collator
->setAttribute(UCOL_NORMALIZATION_MODE
, UCOL_OFF
, status
);
2186 void StringSearchTest::TestSupplementaryCanonical()
2189 while (SUPPLEMENTARYCANONICAL
[count
].text
!= NULL
) {
2190 if (!assertCanonicalEqual(&SUPPLEMENTARYCANONICAL
[count
])) {
2191 errln("Error at test number %d", count
);
2197 void StringSearchTest::TestContractionCanonical()
2201 u_unescape(CONTRACTIONRULE
, temp
, 128);
2202 UnicodeString rules
;
2203 rules
.setTo(temp
, u_strlen(temp
));
2205 UErrorCode status
= U_ZERO_ERROR
;
2206 RuleBasedCollator
*collator
= new RuleBasedCollator(rules
,
2207 getECollationStrength(UCOL_TERTIARY
), UCOL_ON
, status
);
2208 if (U_FAILURE(status
)) {
2209 errln("Error opening collator %s", u_errorName(status
));
2211 UnicodeString
text("text");
2212 UnicodeString
pattern("pattern");
2213 StringSearch
*strsrch
= new StringSearch(pattern
, text
, collator
, NULL
,
2215 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
2216 if (U_FAILURE(status
)) {
2217 errln("Error opening string search %s", u_errorName(status
));
2221 while (CONTRACTIONCANONICAL
[count
].text
!= NULL
) {
2222 u_unescape(CONTRACTIONCANONICAL
[count
].text
, temp
, 128);
2223 text
.setTo(temp
, u_strlen(temp
));
2224 u_unescape(CONTRACTIONCANONICAL
[count
].pattern
, temp
, 128);
2225 pattern
.setTo(temp
, u_strlen(temp
));
2226 strsrch
->setText(text
, status
);
2227 strsrch
->setPattern(pattern
, status
);
2228 if (!assertEqualWithStringSearch(strsrch
,
2229 &CONTRACTIONCANONICAL
[count
])) {
2230 errln("Error at test number %d", count
);
2238 void StringSearchTest::TestUClassID()
2240 char id
= *((char *)StringSearch::getStaticClassID());
2242 errln("Static class id for StringSearch should be 0");
2244 UErrorCode status
= U_ZERO_ERROR
;
2245 UnicodeString
text("text");
2246 UnicodeString
pattern("pattern");
2247 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
, NULL
,
2249 id
= *((char *)strsrch
->getDynamicClassID());
2251 errln("Dynamic class id for StringSearch should be 0");
2256 class TestSearch
: public SearchIterator
2259 TestSearch(const TestSearch
&obj
);
2260 TestSearch(const UnicodeString
&text
,
2261 BreakIterator
*breakiter
,
2262 const UnicodeString
&pattern
);
2265 void setOffset(int32_t position
, UErrorCode
&status
);
2266 int32_t getOffset() const;
2267 SearchIterator
* safeClone() const;
2271 * ICU "poor man's RTTI", returns a UClassID for the actual class.
2275 virtual inline UClassID
getDynamicClassID() const { return getStaticClassID(); }
2278 * ICU "poor man's RTTI", returns a UClassID for this class.
2282 static inline UClassID
getStaticClassID() { return (UClassID
)&fgClassID
; }
2284 UBool
operator!=(const TestSearch
&that
) const;
2286 UnicodeString m_pattern_
;
2289 int32_t handleNext(int32_t position
, UErrorCode
&status
);
2290 int32_t handlePrev(int32_t position
, UErrorCode
&status
);
2291 TestSearch
& operator=(const TestSearch
&that
);
2296 * The address of this static class variable serves as this class's ID
2297 * for ICU "poor man's RTTI".
2299 static const char fgClassID
;
2303 const char TestSearch::fgClassID
=0;
2305 TestSearch::TestSearch(const TestSearch
&obj
) : SearchIterator(obj
)
2307 m_offset_
= obj
.m_offset_
;
2308 m_pattern_
= obj
.m_pattern_
;
2311 TestSearch::TestSearch(const UnicodeString
&text
,
2312 BreakIterator
*breakiter
,
2313 const UnicodeString
&pattern
) : SearchIterator()
2315 m_breakiterator_
= breakiter
;
2316 m_pattern_
= pattern
;
2319 m_pattern_
= pattern
;
2322 TestSearch::~TestSearch()
2327 void TestSearch::setOffset(int32_t position
, UErrorCode
&status
)
2329 if (position
>= 0 && position
<= m_text_
.length()) {
2330 m_offset_
= position
;
2333 status
= U_INDEX_OUTOFBOUNDS_ERROR
;
2337 int32_t TestSearch::getOffset() const
2342 SearchIterator
* TestSearch::safeClone() const
2344 return new TestSearch(m_text_
, m_breakiterator_
, m_pattern_
);
2347 UBool
TestSearch::operator!=(const TestSearch
&that
) const
2349 if (SearchIterator::operator !=(that
)) {
2352 return m_offset_
!= that
.m_offset_
|| m_pattern_
!= that
.m_pattern_
;
2355 int32_t TestSearch::handleNext(int32_t start
, UErrorCode
&status
)
2357 if(U_SUCCESS(status
)) {
2358 int match
= m_text_
.indexOf(m_pattern_
, start
);
2360 m_offset_
= m_text_
.length();
2361 setMatchStart(m_offset_
);
2363 return USEARCH_DONE
;
2365 setMatchStart(match
);
2367 setMatchLength(m_pattern_
.length());
2370 return USEARCH_DONE
;
2374 int32_t TestSearch::handlePrev(int32_t start
, UErrorCode
&status
)
2376 if(U_SUCCESS(status
)) {
2377 int match
= m_text_
.lastIndexOf(m_pattern_
, 0, start
);
2380 setMatchStart(m_offset_
);
2382 return USEARCH_DONE
;
2384 setMatchStart(match
);
2386 setMatchLength(m_pattern_
.length());
2389 return USEARCH_DONE
;
2393 TestSearch
& TestSearch::operator=(const TestSearch
&that
)
2395 SearchIterator::operator=(that
);
2396 m_offset_
= that
.m_offset_
;
2397 m_pattern_
= that
.m_pattern_
;
2401 void StringSearchTest::TestSubclass()
2403 UnicodeString
text("abc abcd abc");
2404 UnicodeString
pattern("abc");
2405 TestSearch
search(text
, NULL
, pattern
);
2406 TestSearch
search2(search
);
2407 int expected
[] = {0, 4, 9};
2408 UErrorCode status
= U_ZERO_ERROR
;
2410 StringCharacterIterator
chariter(text
);
2412 search
.setText(text
, status
);
2413 if (search
.getText() != search2
.getText()) {
2414 errln("Error setting text");
2417 search
.setText(chariter
, status
);
2418 if (search
.getText() != search2
.getText()) {
2419 errln("Error setting text");
2423 // comparing constructors
2425 for (i
= 0; i
< (int)(sizeof(expected
) / sizeof(expected
[0])); i
++) {
2426 if (search
.next(status
) != expected
[i
]) {
2427 errln("Error getting next match");
2429 if (search
.getMatchedLength() != search
.m_pattern_
.length()) {
2430 errln("Error getting next match length");
2433 if (search
.next(status
) != USEARCH_DONE
) {
2434 errln("Error should have reached the end of the iteration");
2436 for (i
= sizeof(expected
) / sizeof(expected
[0]) - 1; i
>= 0; i
--) {
2437 if (search
.previous(status
) != expected
[i
]) {
2438 errln("Error getting previous match");
2440 if (search
.getMatchedLength() != search
.m_pattern_
.length()) {
2441 errln("Error getting previous match length");
2444 if (search
.previous(status
) != USEARCH_DONE
) {
2445 errln("Error should have reached the start of the iteration");
2449 class StubSearchIterator
:public SearchIterator
{
2451 StubSearchIterator(){}
2452 virtual void setOffset(int32_t , UErrorCode
&) {};
2453 virtual int32_t getOffset(void) const {return 0;};
2454 virtual SearchIterator
* safeClone(void) const {return NULL
;};
2455 virtual int32_t handleNext(int32_t , UErrorCode
&){return 0;};
2456 virtual int32_t handlePrev(int32_t , UErrorCode
&) {return 0;};
2457 virtual UClassID
getDynamicClassID() const {
2458 static char classID
= 0;
2459 return (UClassID
)&classID
;
2463 void StringSearchTest::TestCoverage(){
2464 StubSearchIterator stub1
, stub2
;
2465 UErrorCode status
= U_ZERO_ERROR
;
2467 if (stub1
!= stub2
){
2468 errln("new StubSearchIterator should be equal");
2471 stub2
.setText(UnicodeString("ABC"), status
);
2472 if (U_FAILURE(status
)) {
2473 errln("Error: SearchIterator::SetText");
2477 if (stub1
!= stub2
){
2478 errln("SearchIterator::operator = assigned object should be equal");
2482 #endif /* !UCONFIG_NO_BREAK_ITERATION */
2484 #endif /* #if !UCONFIG_NO_COLLATION */