2 *****************************************************************************
3 * Copyright (C) 2001-2016, 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"
22 // private definitions -----------------------------------------------------
24 #define CASE(id,test) \
29 logln((UnicodeString)""); \
31 dataerrln(__FILE__ " cannot test - failed to create collator."); \
38 // public contructors and destructors --------------------------------------
40 StringSearchTest::StringSearchTest()
41 #if !UCONFIG_NO_BREAK_ITERATION
43 m_en_wordbreaker_(NULL
), m_en_characterbreaker_(NULL
)
46 #if !UCONFIG_NO_BREAK_ITERATION
47 UErrorCode status
= U_ZERO_ERROR
;
49 m_en_us_
= (RuleBasedCollator
*)Collator::createInstance("en_US", status
);
50 m_fr_fr_
= (RuleBasedCollator
*)Collator::createInstance("fr_FR", status
);
51 m_de_
= (RuleBasedCollator
*)Collator::createInstance("de_DE", status
);
52 m_es_
= (RuleBasedCollator
*)Collator::createInstance("es_ES", status
);
53 if(U_FAILURE(status
)) {
62 errln("Collator creation failed with %s", u_errorName(status
));
68 rules
.setTo(((RuleBasedCollator
*)m_de_
)->getRules());
69 UChar extrarules
[128];
70 u_unescape(EXTRACOLLATIONRULE
, extrarules
, 128);
71 rules
.append(extrarules
, u_strlen(extrarules
));
74 m_de_
= new RuleBasedCollator(rules
, status
);
76 rules
.setTo(((RuleBasedCollator
*)m_es_
)->getRules());
77 rules
.append(extrarules
, u_strlen(extrarules
));
81 m_es_
= new RuleBasedCollator(rules
, status
);
83 #if !UCONFIG_NO_BREAK_ITERATION
84 m_en_wordbreaker_
= BreakIterator::createWordInstance(
85 Locale::getEnglish(), status
);
86 m_en_characterbreaker_
= BreakIterator::createCharacterInstance(
87 Locale::getEnglish(), status
);
92 StringSearchTest::~StringSearchTest()
94 #if !UCONFIG_NO_BREAK_ITERATION
99 #if !UCONFIG_NO_BREAK_ITERATION
100 delete m_en_wordbreaker_
;
101 delete m_en_characterbreaker_
;
106 // public methods ----------------------------------------------------------
108 void StringSearchTest::runIndexedTest(int32_t index
, UBool exec
,
109 const char* &name
, char* )
111 #if !UCONFIG_NO_BREAK_ITERATION
112 UBool areBroken
= FALSE
;
113 if (m_en_us_
== NULL
&& m_fr_fr_
== NULL
&& m_de_
== NULL
&&
114 m_es_
== NULL
&& m_en_wordbreaker_
== NULL
&&
115 m_en_characterbreaker_
== NULL
&& exec
) {
120 #if !UCONFIG_NO_FILE_IO
121 CASE(0, TestOpenClose
)
123 CASE(1, TestInitialization
)
125 CASE(3, TestNormExact
)
126 CASE(4, TestStrength
)
127 #if UCONFIG_NO_BREAK_ITERATION
129 name
= "TestBreakIterator";
132 CASE(5, TestBreakIterator
)
134 CASE(6, TestVariable
)
136 CASE(8, TestCollator
)
139 CASE(11, TestCompositeBoundaries
)
140 CASE(12, TestGetSetOffset
)
141 CASE(13, TestGetSetAttribute
)
142 CASE(14, TestGetMatch
)
143 CASE(15, TestSetMatch
)
145 CASE(17, TestSupplementary
)
146 CASE(18, TestContraction
)
147 CASE(19, TestIgnorable
)
148 CASE(20, TestCanonical
)
149 CASE(21, TestNormCanonical
)
150 CASE(22, TestStrengthCanonical
)
151 #if UCONFIG_NO_BREAK_ITERATION
153 name
= "TestBreakIteratorCanonical";
156 CASE(23, TestBreakIteratorCanonical
)
158 CASE(24, TestVariableCanonical
)
159 CASE(25, TestOverlapCanonical
)
160 CASE(26, TestCollatorCanonical
)
161 CASE(27, TestPatternCanonical
)
162 CASE(28, TestTextCanonical
)
163 CASE(29, TestCompositeBoundariesCanonical
)
164 CASE(30, TestGetSetOffsetCanonical
)
165 CASE(31, TestSupplementaryCanonical
)
166 CASE(32, TestContractionCanonical
)
167 CASE(33, TestUClassID
)
168 CASE(34, TestSubclass
)
169 CASE(35, TestCoverage
)
170 CASE(36, TestDiacriticMatch
)
171 default: name
= ""; break;
178 #if !UCONFIG_NO_BREAK_ITERATION
179 // private methods ------------------------------------------------------
181 RuleBasedCollator
* StringSearchTest::getCollator(const char *collator
)
183 if (collator
== NULL
) {
186 if (strcmp(collator
, "fr") == 0) {
189 else if (strcmp(collator
, "de") == 0) {
192 else if (strcmp(collator
, "es") == 0) {
200 BreakIterator
* StringSearchTest::getBreakIterator(const char *breaker
)
202 #if UCONFIG_NO_BREAK_ITERATION
205 if (breaker
== NULL
) {
208 if (strcmp(breaker
, "wordbreaker") == 0) {
209 return m_en_wordbreaker_
;
212 return m_en_characterbreaker_
;
217 char * StringSearchTest::toCharString(const UnicodeString
&text
)
219 static char result
[1024];
222 int length
= text
.length();
224 for (; count
< length
; count
++) {
225 UChar ch
= text
[count
];
226 if (ch
>= 0x20 && ch
<= 0x7e) {
227 result
[index
++] = (char)ch
;
230 sprintf(result
+index
, "\\u%04x", ch
);
231 index
+= 6; /* \uxxxx */
239 Collator::ECollationStrength
StringSearchTest::getECollationStrength(
240 const UCollationStrength
&strength
) const
245 return Collator::PRIMARY
;
246 case UCOL_SECONDARY
:
247 return Collator::SECONDARY
;
249 return Collator::TERTIARY
;
251 return Collator::IDENTICAL
;
255 UBool
StringSearchTest::assertEqualWithStringSearch(StringSearch
*strsrch
,
256 const SearchData
*search
)
259 UErrorCode status
= U_ZERO_ERROR
;
260 int32_t matchindex
= search
->offset
[count
];
261 UnicodeString matchtext
;
264 strsrch
->setAttribute(USEARCH_ELEMENT_COMPARISON
, search
->elemCompare
, status
);
265 if (U_FAILURE(status
)) {
266 errln("Error setting USEARCH_ELEMENT_COMPARISON attribute %s", u_errorName(status
));
270 if (strsrch
->getMatchedStart() != USEARCH_DONE
||
271 strsrch
->getMatchedLength() != 0) {
272 errln("Error with the initialization of match start and length");
275 // start of next matches
276 while (U_SUCCESS(status
) && matchindex
>= 0) {
277 matchlength
= search
->size
[count
];
278 strsrch
->next(status
);
279 if (matchindex
!= strsrch
->getMatchedStart() ||
280 matchlength
!= strsrch
->getMatchedLength()) {
281 char *str
= toCharString(strsrch
->getText());
282 errln("Text: %s", str
);
283 str
= toCharString(strsrch
->getPattern());
284 errln("Pattern: %s", str
);
285 errln("Error next match found at %d (len:%d); expected %d (len:%d)",
286 strsrch
->getMatchedStart(), strsrch
->getMatchedLength(),
287 matchindex
, matchlength
);
292 strsrch
->getMatchedText(matchtext
);
294 if (U_FAILURE(status
) ||
295 strsrch
->getText().compareBetween(matchindex
,
296 matchindex
+ matchlength
,
298 matchtext
.length())) {
299 errln("Error getting next matched text");
302 matchindex
= search
->offset
[count
];
304 strsrch
->next(status
);
305 if (strsrch
->getMatchedStart() != USEARCH_DONE
||
306 strsrch
->getMatchedLength() != 0) {
307 char *str
= toCharString(strsrch
->getText());
308 errln("Text: %s", str
);
309 str
= toCharString(strsrch
->getPattern());
310 errln("Pattern: %s", str
);
311 errln("Error next match found at %d (len:%d); expected <NO MATCH>",
312 strsrch
->getMatchedStart(), strsrch
->getMatchedLength());
316 // start of previous matches
317 count
= count
== 0 ? 0 : count
- 1;
318 matchindex
= search
->offset
[count
];
319 while (U_SUCCESS(status
) && matchindex
>= 0) {
320 matchlength
= search
->size
[count
];
321 strsrch
->previous(status
);
322 if (matchindex
!= strsrch
->getMatchedStart() ||
323 matchlength
!= strsrch
->getMatchedLength()) {
324 char *str
= toCharString(strsrch
->getText());
325 errln("Text: %s", str
);
326 str
= toCharString(strsrch
->getPattern());
327 errln("Pattern: %s", str
);
328 errln("Error previous match found at %d (len:%d); expected %d (len:%d)",
329 strsrch
->getMatchedStart(), strsrch
->getMatchedLength(),
330 matchindex
, matchlength
);
334 strsrch
->getMatchedText(matchtext
);
336 if (U_FAILURE(status
) ||
337 strsrch
->getText().compareBetween(matchindex
,
338 matchindex
+ matchlength
,
340 matchtext
.length())) {
341 errln("Error getting previous matched text");
344 matchindex
= count
> 0 ? search
->offset
[count
- 1] : -1;
347 strsrch
->previous(status
);
348 if (strsrch
->getMatchedStart() != USEARCH_DONE
||
349 strsrch
->getMatchedLength() != 0) {
350 char *str
= toCharString(strsrch
->getText());
351 errln("Text: %s", str
);
352 str
= toCharString(strsrch
->getPattern());
353 errln("Pattern: %s", str
);
354 errln("Error previous match found at %d (len:%d); expected <NO MATCH>",
355 strsrch
->getMatchedStart(), strsrch
->getMatchedLength());
360 UBool isOverlap
= (strsrch
->getAttribute(USEARCH_OVERLAP
) == USEARCH_ON
);
362 // start of following matches
364 matchindex
= search
->offset
[count
];
368 strsrch
->following(nextStart
, status
);
370 if (matchindex
< 0) {
371 if (strsrch
->getMatchedStart() != USEARCH_DONE
||
372 strsrch
->getMatchedLength() != 0) {
373 char *str
= toCharString(strsrch
->getText());
374 errln("Text: %s", str
);
375 str
= toCharString(strsrch
->getPattern());
376 errln("Pattern: %s", str
);
377 errln("Error following match starting at %d (overlap:%d) found at %d (len:%d); expected <NO MATCH>",
378 nextStart
, isOverlap
,
379 strsrch
->getMatchedStart(), strsrch
->getMatchedLength());
386 matchlength
= search
->size
[count
];
387 if (strsrch
->getMatchedStart() != matchindex
388 || strsrch
->getMatchedLength() != matchlength
389 || U_FAILURE(status
)) {
390 char *str
= toCharString(strsrch
->getText());
391 errln("Text: %s\n", str
);
392 str
= toCharString(strsrch
->getPattern());
393 errln("Pattern: %s\n", str
);
394 errln("Error following match starting at %d (overlap: %d) found at %d (len:%d); expected %d (len:%d)\n",
395 nextStart
, isOverlap
,
396 strsrch
->getMatchedStart(), strsrch
->getMatchedLength(),
397 matchindex
, matchlength
);
401 if (isOverlap
|| strsrch
->getMatchedLength() == 0) {
402 nextStart
= strsrch
->getMatchedStart() + 1;
404 nextStart
= strsrch
->getMatchedStart() + strsrch
->getMatchedLength();
408 matchindex
= search
->offset
[count
];
411 // start preceding matches
412 count
= -1; // last non-negative offset index, could be -1 if no match
413 while (search
->offset
[count
+ 1] >= 0) {
416 nextStart
= strsrch
->getText().length();
419 strsrch
->preceding(nextStart
, status
);
422 if (strsrch
->getMatchedStart() != USEARCH_DONE
|| strsrch
->getMatchedLength() != 0) {
423 char *str
= toCharString(strsrch
->getText());
424 errln("Text: %s\n", str
);
425 str
= toCharString(strsrch
->getPattern());
426 errln("Pattern: %s\n", str
);
427 errln("Error preceding match starting at %d (overlap: %d) found at %d (len:%d); expected <NO MATCH>\n",
428 nextStart
, isOverlap
,
429 strsrch
->getMatchedStart(),
430 strsrch
->getMatchedLength());
437 matchindex
= search
->offset
[count
];
438 matchlength
= search
->size
[count
];
439 if (strsrch
->getMatchedStart() != matchindex
440 || strsrch
->getMatchedLength() != matchlength
441 || U_FAILURE(status
)) {
442 char *str
= toCharString(strsrch
->getText());
443 errln("Text: %s\n", str
);
444 str
= toCharString(strsrch
->getPattern());
445 errln("Pattern: %s\n", str
);
446 errln("Error preceding match starting at %d (overlap: %d) found at %d (len:%d); expected %d (len:%d)\n",
447 nextStart
, isOverlap
,
448 strsrch
->getMatchedStart(), strsrch
->getMatchedLength(),
449 matchindex
, matchlength
);
453 nextStart
= matchindex
;
457 strsrch
->setAttribute(USEARCH_ELEMENT_COMPARISON
, USEARCH_STANDARD_ELEMENT_COMPARISON
, status
);
461 UBool
StringSearchTest::assertEqual(const SearchData
*search
)
463 UErrorCode status
= U_ZERO_ERROR
;
465 Collator
*collator
= getCollator(search
->collator
);
466 BreakIterator
*breaker
= getBreakIterator(search
->breaker
);
467 StringSearch
*strsrch
, *strsrch2
;
470 #if UCONFIG_NO_BREAK_ITERATION
471 if(search
->breaker
) {
472 return TRUE
; /* skip test */
475 u_unescape(search
->text
, temp
, 128);
478 u_unescape(search
->pattern
, temp
, 128);
479 UnicodeString pattern
;
482 #if !UCONFIG_NO_BREAK_ITERATION
483 if (breaker
!= NULL
) {
484 breaker
->setText(text
);
487 collator
->setStrength(getECollationStrength(search
->strength
));
488 strsrch
= new StringSearch(pattern
, text
, (RuleBasedCollator
*)collator
,
490 if (U_FAILURE(status
)) {
491 errln("Error opening string search %s", u_errorName(status
));
495 if (!assertEqualWithStringSearch(strsrch
, search
)) {
496 collator
->setStrength(getECollationStrength(UCOL_TERTIARY
));
502 strsrch2
= strsrch
->clone();
503 if( strsrch2
== strsrch
|| *strsrch2
!= *strsrch
||
504 !assertEqualWithStringSearch(strsrch2
, search
)
506 infoln("failure with StringSearch.clone()");
507 collator
->setStrength(getECollationStrength(UCOL_TERTIARY
));
514 collator
->setStrength(getECollationStrength(UCOL_TERTIARY
));
519 UBool
StringSearchTest::assertCanonicalEqual(const SearchData
*search
)
521 UErrorCode status
= U_ZERO_ERROR
;
522 Collator
*collator
= getCollator(search
->collator
);
523 BreakIterator
*breaker
= getBreakIterator(search
->breaker
);
524 StringSearch
*strsrch
;
528 #if UCONFIG_NO_BREAK_ITERATION
529 if(search
->breaker
) {
530 return TRUE
; /* skip test */
534 u_unescape(search
->text
, temp
, 128);
537 u_unescape(search
->pattern
, temp
, 128);
538 UnicodeString pattern
;
541 #if !UCONFIG_NO_BREAK_ITERATION
542 if (breaker
!= NULL
) {
543 breaker
->setText(text
);
546 collator
->setStrength(getECollationStrength(search
->strength
));
547 collator
->setAttribute(UCOL_NORMALIZATION_MODE
, UCOL_ON
, status
);
548 strsrch
= new StringSearch(pattern
, text
, (RuleBasedCollator
*)collator
,
550 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
551 if (U_FAILURE(status
)) {
552 errln("Error opening string search %s", u_errorName(status
));
557 if (!assertEqualWithStringSearch(strsrch
, search
)) {
563 collator
->setStrength(getECollationStrength(UCOL_TERTIARY
));
564 collator
->setAttribute(UCOL_NORMALIZATION_MODE
, UCOL_OFF
, status
);
570 UBool
StringSearchTest::assertEqualWithAttribute(const SearchData
*search
,
571 USearchAttributeValue canonical
,
572 USearchAttributeValue overlap
)
574 UErrorCode status
= U_ZERO_ERROR
;
575 Collator
*collator
= getCollator(search
->collator
);
576 BreakIterator
*breaker
= getBreakIterator(search
->breaker
);
577 StringSearch
*strsrch
;
581 #if UCONFIG_NO_BREAK_ITERATION
582 if(search
->breaker
) {
583 return TRUE
; /* skip test */
587 u_unescape(search
->text
, temp
, 128);
590 u_unescape(search
->pattern
, temp
, 128);
591 UnicodeString pattern
;
594 #if !UCONFIG_NO_BREAK_ITERATION
595 if (breaker
!= NULL
) {
596 breaker
->setText(text
);
599 collator
->setStrength(getECollationStrength(search
->strength
));
600 strsrch
= new StringSearch(pattern
, text
, (RuleBasedCollator
*)collator
,
602 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, canonical
, status
);
603 strsrch
->setAttribute(USEARCH_OVERLAP
, overlap
, status
);
605 if (U_FAILURE(status
)) {
606 errln("Error opening string search %s", u_errorName(status
));
610 if (!assertEqualWithStringSearch(strsrch
, search
)) {
611 collator
->setStrength(getECollationStrength(UCOL_TERTIARY
));
615 collator
->setStrength(getECollationStrength(UCOL_TERTIARY
));
620 void StringSearchTest::TestOpenClose()
622 UErrorCode status
= U_ZERO_ERROR
;
623 StringSearch
*result
;
624 BreakIterator
*breakiter
= m_en_wordbreaker_
;
625 UnicodeString pattern
;
627 UnicodeString
temp("a");
628 StringCharacterIterator
chariter(text
);
630 /* testing null arguments */
631 result
= new StringSearch(pattern
, text
, NULL
, NULL
, status
);
632 if (U_SUCCESS(status
)) {
633 errln("Error: NULL arguments should produce an error");
637 chariter
.setText(text
);
638 status
= U_ZERO_ERROR
;
639 result
= new StringSearch(pattern
, chariter
, NULL
, NULL
, status
);
640 if (U_SUCCESS(status
)) {
641 errln("Error: NULL arguments should produce an error");
646 status
= U_ZERO_ERROR
;
647 result
= new StringSearch(pattern
, text
, NULL
, NULL
, status
);
648 if (U_SUCCESS(status
)) {
649 errln("Error: Empty pattern should produce an error");
653 chariter
.setText(text
);
654 status
= U_ZERO_ERROR
;
655 result
= new StringSearch(pattern
, chariter
, NULL
, NULL
, status
);
656 if (U_SUCCESS(status
)) {
657 errln("Error: Empty pattern should produce an error");
662 pattern
.append(temp
);
663 status
= U_ZERO_ERROR
;
664 result
= new StringSearch(pattern
, text
, NULL
, NULL
, status
);
665 if (U_SUCCESS(status
)) {
666 errln("Error: Empty text should produce an error");
670 chariter
.setText(text
);
671 status
= U_ZERO_ERROR
;
672 result
= new StringSearch(pattern
, chariter
, NULL
, NULL
, status
);
673 if (U_SUCCESS(status
)) {
674 errln("Error: Empty text should produce an error");
679 status
= U_ZERO_ERROR
;
680 result
= new StringSearch(pattern
, text
, NULL
, NULL
, status
);
681 if (U_SUCCESS(status
)) {
682 errln("Error: NULL arguments should produce an error");
686 chariter
.setText(text
);
687 status
= U_ZERO_ERROR
;
688 result
= new StringSearch(pattern
, chariter
, NULL
, NULL
, status
);
689 if (U_SUCCESS(status
)) {
690 errln("Error: NULL arguments should produce an error");
694 status
= U_ZERO_ERROR
;
695 result
= new StringSearch(pattern
, text
, m_en_us_
, NULL
, status
);
696 if (U_FAILURE(status
)) {
697 errln("Error: NULL break iterator is valid for opening search");
701 status
= U_ZERO_ERROR
;
702 result
= new StringSearch(pattern
, chariter
, m_en_us_
, NULL
, status
);
703 if (U_FAILURE(status
)) {
704 errln("Error: NULL break iterator is valid for opening search");
708 status
= U_ZERO_ERROR
;
709 result
= new StringSearch(pattern
, text
, Locale::getEnglish(), NULL
, status
);
710 if (U_FAILURE(status
) || result
== NULL
) {
711 errln("Error: NULL break iterator is valid for opening search");
715 status
= U_ZERO_ERROR
;
716 result
= new StringSearch(pattern
, chariter
, Locale::getEnglish(), NULL
, status
);
717 if (U_FAILURE(status
)) {
718 errln("Error: NULL break iterator is valid for opening search");
722 status
= U_ZERO_ERROR
;
723 result
= new StringSearch(pattern
, text
, m_en_us_
, breakiter
, status
);
724 if (U_FAILURE(status
)) {
725 errln("Error: Break iterator is valid for opening search");
729 status
= U_ZERO_ERROR
;
730 result
= new StringSearch(pattern
, chariter
, m_en_us_
, NULL
, status
);
731 if (U_FAILURE(status
)) {
732 errln("Error: Break iterator is valid for opening search");
737 void StringSearchTest::TestInitialization()
739 UErrorCode status
= U_ZERO_ERROR
;
740 UnicodeString pattern
;
742 UnicodeString
temp("a");
743 StringSearch
*result
;
746 /* simple test on the pattern ce construction */
747 pattern
.append(temp
);
748 pattern
.append(temp
);
752 result
= new StringSearch(pattern
, text
, m_en_us_
, NULL
, status
);
753 if (U_FAILURE(status
)) {
754 errln("Error opening search %s", u_errorName(status
));
756 StringSearch
*copy
= new StringSearch(*result
);
757 if (*(copy
->getCollator()) != *(result
->getCollator()) ||
758 copy
->getBreakIterator() != result
->getBreakIterator() ||
759 copy
->getMatchedLength() != result
->getMatchedLength() ||
760 copy
->getMatchedStart() != result
->getMatchedStart() ||
761 copy
->getOffset() != result
->getOffset() ||
762 copy
->getPattern() != result
->getPattern() ||
763 copy
->getText() != result
->getText() ||
764 *(copy
) != *(result
))
766 errln("Error copying StringSearch");
770 copy
= (StringSearch
*)result
->safeClone();
771 if (*(copy
->getCollator()) != *(result
->getCollator()) ||
772 copy
->getBreakIterator() != result
->getBreakIterator() ||
773 copy
->getMatchedLength() != result
->getMatchedLength() ||
774 copy
->getMatchedStart() != result
->getMatchedStart() ||
775 copy
->getOffset() != result
->getOffset() ||
776 copy
->getPattern() != result
->getPattern() ||
777 copy
->getText() != result
->getText() ||
778 *(copy
) != *(result
)) {
779 errln("Error copying StringSearch");
783 /* testing if an extremely large pattern will fail the initialization */
784 for (count
= 0; count
< 512; count
++) {
785 pattern
.append(temp
);
787 result
= new StringSearch(pattern
, text
, m_en_us_
, NULL
, status
);
788 if (*result
!= *result
) {
789 errln("Error: string search object expected to match itself");
791 if (*result
== *copy
) {
792 errln("Error: string search objects are not expected to match");
795 if (*(copy
->getCollator()) != *(result
->getCollator()) ||
796 copy
->getBreakIterator() != result
->getBreakIterator() ||
797 copy
->getMatchedLength() != result
->getMatchedLength() ||
798 copy
->getMatchedStart() != result
->getMatchedStart() ||
799 copy
->getOffset() != result
->getOffset() ||
800 copy
->getPattern() != result
->getPattern() ||
801 copy
->getText() != result
->getText() ||
802 *(copy
) != *(result
)) {
803 errln("Error copying StringSearch");
805 if (U_FAILURE(status
)) {
806 errln("Error opening search %s", u_errorName(status
));
812 void StringSearchTest::TestBasic()
815 while (BASIC
[count
].text
!= NULL
) {
816 //printf("count %d", count);
817 if (!assertEqual(&BASIC
[count
])) {
818 infoln("Error at test number %d", count
);
824 void StringSearchTest::TestNormExact()
827 UErrorCode status
= U_ZERO_ERROR
;
828 m_en_us_
->setAttribute(UCOL_NORMALIZATION_MODE
, UCOL_ON
, status
);
829 if (U_FAILURE(status
)) {
830 errln("Error setting collation normalization %s",
831 u_errorName(status
));
833 while (BASIC
[count
].text
!= NULL
) {
834 if (!assertEqual(&BASIC
[count
])) {
835 infoln("Error at test number %d", count
);
840 while (NORMEXACT
[count
].text
!= NULL
) {
841 if (!assertEqual(&NORMEXACT
[count
])) {
842 infoln("Error at test number %d", count
);
846 m_en_us_
->setAttribute(UCOL_NORMALIZATION_MODE
, UCOL_OFF
, status
);
848 while (NONNORMEXACT
[count
].text
!= NULL
) {
849 if (!assertEqual(&NONNORMEXACT
[count
])) {
850 infoln("Error at test number %d", count
);
856 void StringSearchTest::TestStrength()
859 while (STRENGTH
[count
].text
!= NULL
) {
860 if (!assertEqual(&STRENGTH
[count
])) {
861 infoln("Error at test number %d", count
);
867 #if !UCONFIG_NO_BREAK_ITERATION
869 void StringSearchTest::TestBreakIterator()
872 u_unescape(BREAKITERATOREXACT
[0].text
, temp
, 128);
874 text
.setTo(temp
, u_strlen(temp
));
875 u_unescape(BREAKITERATOREXACT
[0].pattern
, temp
, 128);
876 UnicodeString pattern
;
877 pattern
.setTo(temp
, u_strlen(temp
));
879 UErrorCode status
= U_ZERO_ERROR
;
880 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
, NULL
,
882 if (U_FAILURE(status
)) {
883 errln("Error opening string search %s", u_errorName(status
));
886 strsrch
->setBreakIterator(NULL
, status
);
887 if (U_FAILURE(status
) || strsrch
->getBreakIterator() != NULL
) {
888 errln("Error usearch_getBreakIterator returned wrong object");
891 strsrch
->setBreakIterator(m_en_characterbreaker_
, status
);
892 if (U_FAILURE(status
) ||
893 strsrch
->getBreakIterator() != m_en_characterbreaker_
) {
894 errln("Error usearch_getBreakIterator returned wrong object");
897 strsrch
->setBreakIterator(m_en_wordbreaker_
, status
);
898 if (U_FAILURE(status
) ||
899 strsrch
->getBreakIterator() != m_en_wordbreaker_
) {
900 errln("Error usearch_getBreakIterator returned wrong object");
907 // special purposes for tests numbers 0-3
908 const SearchData
*search
= &(BREAKITERATOREXACT
[count
]);
909 RuleBasedCollator
*collator
= getCollator(search
->collator
);
910 BreakIterator
*breaker
= getBreakIterator(search
->breaker
);
911 StringSearch
*strsrch
;
913 u_unescape(search
->text
, temp
, 128);
914 text
.setTo(temp
, u_strlen(temp
));
915 u_unescape(search
->pattern
, temp
, 128);
916 pattern
.setTo(temp
, u_strlen(temp
));
917 if (breaker
!= NULL
) {
918 breaker
->setText(text
);
920 collator
->setStrength(getECollationStrength(search
->strength
));
922 strsrch
= new StringSearch(pattern
, text
, collator
, breaker
, status
);
923 if (U_FAILURE(status
) ||
924 strsrch
->getBreakIterator() != breaker
) {
925 errln("Error setting break iterator");
926 if (strsrch
!= NULL
) {
930 if (!assertEqualWithStringSearch(strsrch
, search
)) {
931 collator
->setStrength(getECollationStrength(UCOL_TERTIARY
));
934 search
= &(BREAKITERATOREXACT
[count
+ 1]);
935 breaker
= getBreakIterator(search
->breaker
);
936 if (breaker
!= NULL
) {
937 breaker
->setText(text
);
939 strsrch
->setBreakIterator(breaker
, status
);
940 if (U_FAILURE(status
) ||
941 strsrch
->getBreakIterator() != breaker
) {
942 errln("Error setting break iterator");
946 if (!assertEqualWithStringSearch(strsrch
, search
)) {
947 infoln("Error at test number %d", count
);
953 while (BREAKITERATOREXACT
[count
].text
!= NULL
) {
954 if (!assertEqual(&BREAKITERATOREXACT
[count
])) {
955 infoln("Error at test number %d", count
);
963 void StringSearchTest::TestVariable()
966 UErrorCode status
= U_ZERO_ERROR
;
967 m_en_us_
->setAttribute(UCOL_ALTERNATE_HANDLING
, UCOL_SHIFTED
, status
);
968 if (U_FAILURE(status
)) {
969 errln("Error setting collation alternate attribute %s",
970 u_errorName(status
));
972 while (VARIABLE
[count
].text
!= NULL
) {
973 logln("variable %d", count
);
974 if (!assertEqual(&VARIABLE
[count
])) {
975 infoln("Error at test number %d", count
);
979 m_en_us_
->setAttribute(UCOL_ALTERNATE_HANDLING
, UCOL_NON_IGNORABLE
,
983 void StringSearchTest::TestOverlap()
986 while (OVERLAP
[count
].text
!= NULL
) {
987 if (!assertEqualWithAttribute(&OVERLAP
[count
], USEARCH_OFF
,
989 errln("Error at overlap test number %d", count
);
994 while (NONOVERLAP
[count
].text
!= NULL
) {
995 if (!assertEqual(&NONOVERLAP
[count
])) {
996 errln("Error at non overlap test number %d", count
);
1003 const SearchData
*search
= &(OVERLAP
[count
]);
1005 u_unescape(search
->text
, temp
, 128);
1007 text
.setTo(temp
, u_strlen(temp
));
1008 u_unescape(search
->pattern
, temp
, 128);
1009 UnicodeString pattern
;
1010 pattern
.setTo(temp
, u_strlen(temp
));
1012 RuleBasedCollator
*collator
= getCollator(search
->collator
);
1013 UErrorCode status
= U_ZERO_ERROR
;
1014 StringSearch
*strsrch
= new StringSearch(pattern
, text
,
1018 strsrch
->setAttribute(USEARCH_OVERLAP
, USEARCH_ON
, status
);
1019 if (U_FAILURE(status
) ||
1020 strsrch
->getAttribute(USEARCH_OVERLAP
) != USEARCH_ON
) {
1021 errln("Error setting overlap option");
1023 if (!assertEqualWithStringSearch(strsrch
, search
)) {
1028 search
= &(NONOVERLAP
[count
]);
1029 strsrch
->setAttribute(USEARCH_OVERLAP
, USEARCH_OFF
, status
);
1030 if (U_FAILURE(status
) ||
1031 strsrch
->getAttribute(USEARCH_OVERLAP
) != USEARCH_OFF
) {
1032 errln("Error setting overlap option");
1035 if (!assertEqualWithStringSearch(strsrch
, search
)) {
1037 errln("Error at test number %d", count
);
1045 void StringSearchTest::TestCollator()
1047 // test collator that thinks "o" and "p" are the same thing
1049 u_unescape(COLLATOR
[0].text
, temp
, 128);
1051 text
.setTo(temp
, u_strlen(temp
));
1052 u_unescape(COLLATOR
[0].pattern
, temp
, 128);
1053 UnicodeString pattern
;
1054 pattern
.setTo(temp
, u_strlen(temp
));
1056 UErrorCode status
= U_ZERO_ERROR
;
1057 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
, NULL
,
1059 if (U_FAILURE(status
)) {
1060 errln("Error opening string search %s", u_errorName(status
));
1064 if (!assertEqualWithStringSearch(strsrch
, &COLLATOR
[0])) {
1069 u_unescape(TESTCOLLATORRULE
, temp
, 128);
1070 UnicodeString rules
;
1071 rules
.setTo(temp
, u_strlen(temp
));
1072 RuleBasedCollator
*tailored
= new RuleBasedCollator(rules
, status
);
1073 tailored
->setStrength(getECollationStrength(COLLATOR
[1].strength
));
1075 if (U_FAILURE(status
)) {
1076 errln("Error opening rule based collator %s", u_errorName(status
));
1082 strsrch
->setCollator(tailored
, status
);
1083 if (U_FAILURE(status
) || (*strsrch
->getCollator()) != (*tailored
)) {
1084 errln("Error setting rule based collator");
1089 if (!assertEqualWithStringSearch(strsrch
, &COLLATOR
[1])) {
1095 strsrch
->setCollator(m_en_us_
, status
);
1097 if (U_FAILURE(status
) || (*strsrch
->getCollator()) != (*m_en_us_
)) {
1098 errln("Error setting rule based collator");
1102 if (!assertEqualWithStringSearch(strsrch
, &COLLATOR
[0])) {
1103 errln("Error searching collator test");
1109 void StringSearchTest::TestPattern()
1114 u_unescape(PATTERN
[0].text
, temp
, 512);
1116 text
.setTo(temp
, u_strlen(temp
));
1117 u_unescape(PATTERN
[0].pattern
, temp
, 512);
1118 UnicodeString pattern
;
1119 pattern
.setTo(temp
, u_strlen(temp
));
1121 m_en_us_
->setStrength(getECollationStrength(PATTERN
[0].strength
));
1122 UErrorCode status
= U_ZERO_ERROR
;
1123 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
, NULL
,
1126 if (U_FAILURE(status
)) {
1127 errln("Error opening string search %s", u_errorName(status
));
1128 m_en_us_
->setStrength(getECollationStrength(UCOL_TERTIARY
));
1129 if (strsrch
!= NULL
) {
1134 if (strsrch
->getPattern() != pattern
) {
1135 errln("Error setting pattern");
1137 if (!assertEqualWithStringSearch(strsrch
, &PATTERN
[0])) {
1138 m_en_us_
->setStrength(getECollationStrength(UCOL_TERTIARY
));
1139 if (strsrch
!= NULL
) {
1145 u_unescape(PATTERN
[1].pattern
, temp
, 512);
1146 pattern
.setTo(temp
, u_strlen(temp
));
1147 strsrch
->setPattern(pattern
, status
);
1148 if (pattern
!= strsrch
->getPattern()) {
1149 errln("Error setting pattern");
1150 m_en_us_
->setStrength(getECollationStrength(UCOL_TERTIARY
));
1151 if (strsrch
!= NULL
) {
1157 if (U_FAILURE(status
)) {
1158 errln("Error setting pattern %s", u_errorName(status
));
1160 if (!assertEqualWithStringSearch(strsrch
, &PATTERN
[1])) {
1161 m_en_us_
->setStrength(getECollationStrength(UCOL_TERTIARY
));
1162 if (strsrch
!= NULL
) {
1168 u_unescape(PATTERN
[0].pattern
, temp
, 512);
1169 pattern
.setTo(temp
, u_strlen(temp
));
1170 strsrch
->setPattern(pattern
, status
);
1171 if (pattern
!= strsrch
->getPattern()) {
1172 errln("Error setting pattern");
1173 m_en_us_
->setStrength(getECollationStrength(UCOL_TERTIARY
));
1174 if (strsrch
!= NULL
) {
1180 if (U_FAILURE(status
)) {
1181 errln("Error setting pattern %s", u_errorName(status
));
1183 if (!assertEqualWithStringSearch(strsrch
, &PATTERN
[0])) {
1184 m_en_us_
->setStrength(getECollationStrength(UCOL_TERTIARY
));
1185 if (strsrch
!= NULL
) {
1190 /* enormous pattern size to see if this crashes */
1191 for (templength
= 0; templength
!= 512; templength
++) {
1192 temp
[templength
] = 0x61;
1195 pattern
.setTo(temp
, 511);
1196 strsrch
->setPattern(pattern
, status
);
1197 if (U_FAILURE(status
)) {
1198 errln("Error setting pattern with size 512, %s", u_errorName(status
));
1200 m_en_us_
->setStrength(getECollationStrength(UCOL_TERTIARY
));
1201 if (strsrch
!= NULL
) {
1206 void StringSearchTest::TestText()
1209 u_unescape(TEXT
[0].text
, temp
, 128);
1211 text
.setTo(temp
, u_strlen(temp
));
1212 u_unescape(TEXT
[0].pattern
, temp
, 128);
1213 UnicodeString pattern
;
1214 pattern
.setTo(temp
, u_strlen(temp
));
1216 UErrorCode status
= U_ZERO_ERROR
;
1217 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
, NULL
,
1219 if (U_FAILURE(status
)) {
1220 errln("Error opening string search %s", u_errorName(status
));
1223 if (text
!= strsrch
->getText()) {
1224 errln("Error setting text");
1226 if (!assertEqualWithStringSearch(strsrch
, &TEXT
[0])) {
1231 u_unescape(TEXT
[1].text
, temp
, 128);
1232 text
.setTo(temp
, u_strlen(temp
));
1233 strsrch
->setText(text
, status
);
1234 if (text
!= strsrch
->getText()) {
1235 errln("Error setting text");
1239 if (U_FAILURE(status
)) {
1240 errln("Error setting text %s", u_errorName(status
));
1242 if (!assertEqualWithStringSearch(strsrch
, &TEXT
[1])) {
1247 u_unescape(TEXT
[0].text
, temp
, 128);
1248 text
.setTo(temp
, u_strlen(temp
));
1249 StringCharacterIterator
chariter(text
);
1250 strsrch
->setText(chariter
, status
);
1251 if (text
!= strsrch
->getText()) {
1252 errln("Error setting text");
1256 if (U_FAILURE(status
)) {
1257 errln("Error setting pattern %s", u_errorName(status
));
1259 if (!assertEqualWithStringSearch(strsrch
, &TEXT
[0])) {
1260 errln("Error searching within set text");
1265 void StringSearchTest::TestCompositeBoundaries()
1268 while (COMPOSITEBOUNDARIES
[count
].text
!= NULL
) {
1269 logln("composite %d", count
);
1270 if (!assertEqual(&COMPOSITEBOUNDARIES
[count
])) {
1271 errln("Error at test number %d", count
);
1277 void StringSearchTest::TestGetSetOffset()
1279 UErrorCode status
= U_ZERO_ERROR
;
1280 UnicodeString
pattern("1234567890123456");
1281 UnicodeString
text("12345678901234567890123456789012");
1282 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
,
1284 /* testing out of bounds error */
1285 strsrch
->setOffset(-1, status
);
1286 if (U_SUCCESS(status
)) {
1287 errln("Error expecting set offset error");
1289 strsrch
->setOffset(128, status
);
1290 if (U_SUCCESS(status
)) {
1291 errln("Error expecting set offset error");
1294 while (BASIC
[index
].text
!= NULL
) {
1295 UErrorCode status
= U_ZERO_ERROR
;
1296 SearchData search
= BASIC
[index
++];
1299 u_unescape(search
.text
, temp
, 128);
1300 text
.setTo(temp
, u_strlen(temp
));
1301 u_unescape(search
.pattern
, temp
, 128);
1302 pattern
.setTo(temp
, u_strlen(temp
));
1303 strsrch
->setText(text
, status
);
1304 strsrch
->setPattern(pattern
, status
);
1305 strsrch
->getCollator()->setStrength(getECollationStrength(
1310 int32_t matchindex
= search
.offset
[count
];
1311 while (U_SUCCESS(status
) && matchindex
>= 0) {
1312 int32_t matchlength
= search
.size
[count
];
1313 strsrch
->next(status
);
1314 if (matchindex
!= strsrch
->getMatchedStart() ||
1315 matchlength
!= strsrch
->getMatchedLength()) {
1316 char *str
= toCharString(strsrch
->getText());
1317 errln("Text: %s", str
);
1318 str
= toCharString(strsrch
->getPattern());
1319 errln("Pattern: %s", str
);
1320 errln("Error match found at %d %d",
1321 strsrch
->getMatchedStart(),
1322 strsrch
->getMatchedLength());
1325 matchindex
= search
.offset
[count
+ 1] == -1 ? -1 :
1326 search
.offset
[count
+ 2];
1327 if (search
.offset
[count
+ 1] != -1) {
1328 strsrch
->setOffset(search
.offset
[count
+ 1] + 1, status
);
1329 if (strsrch
->getOffset() != search
.offset
[count
+ 1] + 1) {
1330 errln("Error setting offset\n");
1337 strsrch
->next(status
);
1338 if (strsrch
->getMatchedStart() != USEARCH_DONE
) {
1339 char *str
= toCharString(strsrch
->getText());
1340 errln("Text: %s", str
);
1341 str
= toCharString(strsrch
->getPattern());
1342 errln("Pattern: %s", str
);
1343 errln("Error match found at %d %d",
1344 strsrch
->getMatchedStart(),
1345 strsrch
->getMatchedLength());
1349 strsrch
->getCollator()->setStrength(getECollationStrength(
1354 void StringSearchTest::TestGetSetAttribute()
1356 UErrorCode status
= U_ZERO_ERROR
;
1357 UnicodeString
pattern("pattern");
1358 UnicodeString
text("text");
1359 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
, NULL
,
1361 if (U_FAILURE(status
)) {
1362 errln("Error opening search %s", u_errorName(status
));
1366 strsrch
->setAttribute(USEARCH_OVERLAP
, USEARCH_DEFAULT
, status
);
1367 if (U_FAILURE(status
) ||
1368 strsrch
->getAttribute(USEARCH_OVERLAP
) != USEARCH_OFF
) {
1369 errln("Error setting overlap to the default");
1371 strsrch
->setAttribute(USEARCH_OVERLAP
, USEARCH_ON
, status
);
1372 if (U_FAILURE(status
) ||
1373 strsrch
->getAttribute(USEARCH_OVERLAP
) != USEARCH_ON
) {
1374 errln("Error setting overlap true");
1376 strsrch
->setAttribute(USEARCH_OVERLAP
, USEARCH_OFF
, status
);
1377 if (U_FAILURE(status
) ||
1378 strsrch
->getAttribute(USEARCH_OVERLAP
) != USEARCH_OFF
) {
1379 errln("Error setting overlap false");
1381 strsrch
->setAttribute(USEARCH_OVERLAP
, USEARCH_ATTRIBUTE_VALUE_COUNT
,
1383 if (U_SUCCESS(status
)) {
1384 errln("Error setting overlap to illegal value");
1386 status
= U_ZERO_ERROR
;
1387 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_DEFAULT
, status
);
1388 if (U_FAILURE(status
) ||
1389 strsrch
->getAttribute(USEARCH_CANONICAL_MATCH
) != USEARCH_OFF
) {
1390 errln("Error setting canonical match to the default");
1392 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
1393 if (U_FAILURE(status
) ||
1394 strsrch
->getAttribute(USEARCH_CANONICAL_MATCH
) != USEARCH_ON
) {
1395 errln("Error setting canonical match true");
1397 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_OFF
, status
);
1398 if (U_FAILURE(status
) ||
1399 strsrch
->getAttribute(USEARCH_CANONICAL_MATCH
) != USEARCH_OFF
) {
1400 errln("Error setting canonical match false");
1402 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
,
1403 USEARCH_ATTRIBUTE_VALUE_COUNT
, status
);
1404 if (U_SUCCESS(status
)) {
1405 errln("Error setting canonical match to illegal value");
1407 status
= U_ZERO_ERROR
;
1408 strsrch
->setAttribute(USEARCH_ATTRIBUTE_COUNT
, USEARCH_DEFAULT
, status
);
1409 if (U_SUCCESS(status
)) {
1410 errln("Error setting illegal attribute success");
1416 void StringSearchTest::TestGetMatch()
1419 SearchData search
= MATCH
[0];
1420 u_unescape(search
.text
, temp
, 128);
1422 text
.setTo(temp
, u_strlen(temp
));
1423 u_unescape(search
.pattern
, temp
, 128);
1424 UnicodeString pattern
;
1425 pattern
.setTo(temp
, u_strlen(temp
));
1427 UErrorCode status
= U_ZERO_ERROR
;
1428 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
, NULL
,
1430 if (U_FAILURE(status
)) {
1431 errln("Error opening string search %s", u_errorName(status
));
1432 if (strsrch
!= NULL
) {
1439 int32_t matchindex
= search
.offset
[count
];
1440 UnicodeString matchtext
;
1441 while (U_SUCCESS(status
) && matchindex
>= 0) {
1442 int32_t matchlength
= search
.size
[count
];
1443 strsrch
->next(status
);
1444 if (matchindex
!= strsrch
->getMatchedStart() ||
1445 matchlength
!= strsrch
->getMatchedLength()) {
1446 char *str
= toCharString(strsrch
->getText());
1447 errln("Text: %s", str
);
1448 str
= toCharString(strsrch
->getPattern());
1449 errln("Pattern: %s", str
);
1450 errln("Error match found at %d %d", strsrch
->getMatchedStart(),
1451 strsrch
->getMatchedLength());
1456 status
= U_ZERO_ERROR
;
1457 strsrch
->getMatchedText(matchtext
);
1458 if (matchtext
.length() != matchlength
|| U_FAILURE(status
)){
1459 errln("Error getting match text");
1461 matchindex
= search
.offset
[count
];
1463 status
= U_ZERO_ERROR
;
1464 strsrch
->next(status
);
1465 if (strsrch
->getMatchedStart() != USEARCH_DONE
||
1466 strsrch
->getMatchedLength() != 0) {
1467 errln("Error end of match not found");
1469 status
= U_ZERO_ERROR
;
1470 strsrch
->getMatchedText(matchtext
);
1471 if (matchtext
.length() != 0) {
1472 errln("Error getting null matches");
1477 void StringSearchTest::TestSetMatch()
1480 while (MATCH
[count
].text
!= NULL
) {
1481 SearchData search
= MATCH
[count
];
1483 UErrorCode status
= U_ZERO_ERROR
;
1484 u_unescape(search
.text
, temp
, 128);
1486 text
.setTo(temp
, u_strlen(temp
));
1487 u_unescape(search
.pattern
, temp
, 128);
1488 UnicodeString pattern
;
1489 pattern
.setTo(temp
, u_strlen(temp
));
1491 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
,
1493 if (U_FAILURE(status
)) {
1494 errln("Error opening string search %s", u_errorName(status
));
1495 if (strsrch
!= NULL
) {
1502 while (search
.offset
[size
] != -1) {
1506 if (strsrch
->first(status
) != search
.offset
[0] || U_FAILURE(status
)) {
1507 errln("Error getting first match");
1509 if (strsrch
->last(status
) != search
.offset
[size
-1] ||
1510 U_FAILURE(status
)) {
1511 errln("Error getting last match");
1515 while (index
< size
) {
1516 if (index
+ 2 < size
) {
1517 if (strsrch
->following(search
.offset
[index
+ 2] - 1, status
)
1518 != search
.offset
[index
+ 2] || U_FAILURE(status
)) {
1519 errln("Error getting following match at index %d",
1520 search
.offset
[index
+ 2] - 1);
1523 if (index
+ 1 < size
) {
1524 if (strsrch
->preceding(search
.offset
[index
+ 1] +
1525 search
.size
[index
+ 1] + 1,
1526 status
) != search
.offset
[index
+ 1] ||
1527 U_FAILURE(status
)) {
1528 errln("Error getting preceeding match at index %d",
1529 search
.offset
[index
+ 1] + 1);
1534 status
= U_ZERO_ERROR
;
1535 if (strsrch
->following(text
.length(), status
) != USEARCH_DONE
) {
1536 errln("Error expecting out of bounds match");
1538 if (strsrch
->preceding(0, status
) != USEARCH_DONE
) {
1539 errln("Error expecting out of bounds match");
1546 void StringSearchTest::TestReset()
1548 UErrorCode status
= U_ZERO_ERROR
;
1549 UnicodeString
text("fish fish");
1550 UnicodeString
pattern("s");
1551 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
, NULL
,
1553 if (U_FAILURE(status
)) {
1554 errln("Error opening string search %s", u_errorName(status
));
1555 if (strsrch
!= NULL
) {
1560 strsrch
->setAttribute(USEARCH_OVERLAP
, USEARCH_ON
, status
);
1561 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
1562 strsrch
->setOffset(9, status
);
1563 if (U_FAILURE(status
)) {
1564 errln("Error setting attributes and offsets");
1568 if (strsrch
->getAttribute(USEARCH_OVERLAP
) != USEARCH_OFF
||
1569 strsrch
->getAttribute(USEARCH_CANONICAL_MATCH
) != USEARCH_OFF
||
1570 strsrch
->getOffset() != 0 || strsrch
->getMatchedLength() != 0 ||
1571 strsrch
->getMatchedStart() != USEARCH_DONE
) {
1572 errln("Error resetting string search");
1574 strsrch
->previous(status
);
1575 if (strsrch
->getMatchedStart() != 7 ||
1576 strsrch
->getMatchedLength() != 1) {
1577 errln("Error resetting string search\n");
1583 void StringSearchTest::TestSupplementary()
1586 while (SUPPLEMENTARY
[count
].text
!= NULL
) {
1587 if (!assertEqual(&SUPPLEMENTARY
[count
])) {
1588 errln("Error at test number %d", count
);
1594 void StringSearchTest::TestContraction()
1597 UErrorCode status
= U_ZERO_ERROR
;
1599 u_unescape(CONTRACTIONRULE
, temp
, 128);
1600 UnicodeString rules
;
1601 rules
.setTo(temp
, u_strlen(temp
));
1602 RuleBasedCollator
*collator
= new RuleBasedCollator(rules
,
1603 getECollationStrength(UCOL_TERTIARY
), UCOL_ON
, status
);
1604 if (U_FAILURE(status
)) {
1605 errln("Error opening collator %s", u_errorName(status
));
1607 UnicodeString
text("text");
1608 UnicodeString
pattern("pattern");
1609 StringSearch
*strsrch
= new StringSearch(pattern
, text
, collator
, NULL
,
1611 if (U_FAILURE(status
)) {
1612 errln("Error opening string search %s", u_errorName(status
));
1616 while (CONTRACTION
[count
].text
!= NULL
) {
1617 u_unescape(CONTRACTION
[count
].text
, temp
, 128);
1618 text
.setTo(temp
, u_strlen(temp
));
1619 u_unescape(CONTRACTION
[count
].pattern
, temp
, 128);
1620 pattern
.setTo(temp
, u_strlen(temp
));
1621 strsrch
->setText(text
, status
);
1622 strsrch
->setPattern(pattern
, status
);
1623 if (!assertEqualWithStringSearch(strsrch
, &CONTRACTION
[count
])) {
1624 errln("Error at test number %d", count
);
1632 void StringSearchTest::TestIgnorable()
1635 u_unescape(IGNORABLERULE
, temp
, 128);
1636 UnicodeString rules
;
1637 rules
.setTo(temp
, u_strlen(temp
));
1638 UErrorCode status
= U_ZERO_ERROR
;
1640 RuleBasedCollator
*collator
= new RuleBasedCollator(rules
,
1641 getECollationStrength(IGNORABLE
[count
].strength
),
1643 if (U_FAILURE(status
)) {
1644 errln("Error opening collator %s", u_errorName(status
));
1647 UnicodeString
pattern("pattern");
1648 UnicodeString
text("text");
1649 StringSearch
*strsrch
= new StringSearch(pattern
, text
, collator
, NULL
,
1651 if (U_FAILURE(status
)) {
1652 errln("Error opening string search %s", u_errorName(status
));
1657 while (IGNORABLE
[count
].text
!= NULL
) {
1658 u_unescape(IGNORABLE
[count
].text
, temp
, 128);
1659 text
.setTo(temp
, u_strlen(temp
));
1660 u_unescape(IGNORABLE
[count
].pattern
, temp
, 128);
1661 pattern
.setTo(temp
, u_strlen(temp
));
1662 strsrch
->setText(text
, status
);
1663 strsrch
->setPattern(pattern
, status
);
1664 if (!assertEqualWithStringSearch(strsrch
, &IGNORABLE
[count
])) {
1665 errln("Error at test number %d", count
);
1673 void StringSearchTest::TestDiacriticMatch()
1676 UErrorCode status
= U_ZERO_ERROR
;
1678 RuleBasedCollator
* coll
= NULL
;
1679 StringSearch
*strsrch
= NULL
;
1681 UnicodeString
pattern("pattern");
1682 UnicodeString
text("text");
1684 const SearchData
*search
;
1686 search
= &(DIACRITICMATCH
[count
]);
1687 while (search
->text
!= NULL
) {
1688 coll
= getCollator(search
->collator
);
1689 coll
->setStrength(getECollationStrength(search
->strength
));
1690 strsrch
= new StringSearch(pattern
, text
, coll
, getBreakIterator(search
->breaker
), status
);
1691 if (U_FAILURE(status
)) {
1692 errln("Error opening string search %s", u_errorName(status
));
1695 u_unescape(search
->text
, temp
, 128);
1696 text
.setTo(temp
, u_strlen(temp
));
1697 u_unescape(search
->pattern
, temp
, 128);
1698 pattern
.setTo(temp
, u_strlen(temp
));
1699 strsrch
->setText(text
, status
);
1700 strsrch
->setPattern(pattern
, status
);
1701 if (!assertEqualWithStringSearch(strsrch
, search
)) {
1702 errln("Error at test number %d", count
);
1704 search
= &(DIACRITICMATCH
[++count
]);
1710 void StringSearchTest::TestCanonical()
1713 while (BASICCANONICAL
[count
].text
!= NULL
) {
1714 if (!assertCanonicalEqual(&BASICCANONICAL
[count
])) {
1715 errln("Error at test number %d", count
);
1721 void StringSearchTest::TestNormCanonical()
1723 UErrorCode status
= U_ZERO_ERROR
;
1724 m_en_us_
->setAttribute(UCOL_NORMALIZATION_MODE
, UCOL_ON
, status
);
1726 while (NORMCANONICAL
[count
].text
!= NULL
) {
1727 if (!assertCanonicalEqual(&NORMCANONICAL
[count
])) {
1728 errln("Error at test number %d", count
);
1732 m_en_us_
->setAttribute(UCOL_NORMALIZATION_MODE
, UCOL_OFF
, status
);
1735 void StringSearchTest::TestStrengthCanonical()
1738 while (STRENGTHCANONICAL
[count
].text
!= NULL
) {
1739 if (!assertCanonicalEqual(&STRENGTHCANONICAL
[count
])) {
1740 errln("Error at test number %d", count
);
1746 #if !UCONFIG_NO_BREAK_ITERATION
1748 void StringSearchTest::TestBreakIteratorCanonical()
1750 UErrorCode status
= U_ZERO_ERROR
;
1754 // special purposes for tests numbers 0-3
1756 const SearchData
*search
= &(BREAKITERATORCANONICAL
[count
]);
1758 u_unescape(search
->text
, temp
, 128);
1760 text
.setTo(temp
, u_strlen(temp
));
1761 u_unescape(search
->pattern
, temp
, 128);
1762 UnicodeString pattern
;
1763 pattern
.setTo(temp
, u_strlen(temp
));
1764 RuleBasedCollator
*collator
= getCollator(search
->collator
);
1765 collator
->setStrength(getECollationStrength(search
->strength
));
1767 BreakIterator
*breaker
= getBreakIterator(search
->breaker
);
1768 StringSearch
*strsrch
= new StringSearch(pattern
, text
, collator
,
1770 if (U_FAILURE(status
)) {
1771 errln("Error creating string search data");
1774 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
1775 if (U_FAILURE(status
) ||
1776 strsrch
->getBreakIterator() != breaker
) {
1777 errln("Error setting break iterator");
1781 if (!assertEqualWithStringSearch(strsrch
, search
)) {
1782 collator
->setStrength(getECollationStrength(UCOL_TERTIARY
));
1786 search
= &(BREAKITERATOREXACT
[count
+ 1]);
1787 breaker
= getBreakIterator(search
->breaker
);
1788 if (breaker
== NULL
) {
1789 errln("Error creating BreakIterator");
1792 breaker
->setText(strsrch
->getText());
1793 strsrch
->setBreakIterator(breaker
, status
);
1794 if (U_FAILURE(status
) || strsrch
->getBreakIterator() != breaker
) {
1795 errln("Error setting break iterator");
1800 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
1801 if (!assertEqualWithStringSearch(strsrch
, search
)) {
1802 errln("Error at test number %d", count
);
1809 while (BREAKITERATORCANONICAL
[count
].text
!= NULL
) {
1810 if (!assertEqual(&BREAKITERATORCANONICAL
[count
])) {
1811 errln("Error at test number %d", count
);
1820 void StringSearchTest::TestVariableCanonical()
1823 UErrorCode status
= U_ZERO_ERROR
;
1824 m_en_us_
->setAttribute(UCOL_ALTERNATE_HANDLING
, UCOL_SHIFTED
, status
);
1825 if (U_FAILURE(status
)) {
1826 errln("Error setting collation alternate attribute %s",
1827 u_errorName(status
));
1829 while (VARIABLE
[count
].text
!= NULL
) {
1830 logln("variable %d", count
);
1831 if (!assertCanonicalEqual(&VARIABLE
[count
])) {
1832 errln("Error at test number %d", count
);
1836 m_en_us_
->setAttribute(UCOL_ALTERNATE_HANDLING
, UCOL_NON_IGNORABLE
,
1840 void StringSearchTest::TestOverlapCanonical()
1843 while (OVERLAPCANONICAL
[count
].text
!= NULL
) {
1844 if (!assertEqualWithAttribute(&OVERLAPCANONICAL
[count
], USEARCH_ON
,
1846 errln("Error at overlap test number %d", count
);
1851 while (NONOVERLAP
[count
].text
!= NULL
) {
1852 if (!assertCanonicalEqual(&NONOVERLAPCANONICAL
[count
])) {
1853 errln("Error at non overlap test number %d", count
);
1861 const SearchData
*search
= &(OVERLAPCANONICAL
[count
]);
1862 UErrorCode status
= U_ZERO_ERROR
;
1864 u_unescape(search
->text
, temp
, 128);
1866 text
.setTo(temp
, u_strlen(temp
));
1867 u_unescape(search
->pattern
, temp
, 128);
1868 UnicodeString pattern
;
1869 pattern
.setTo(temp
, u_strlen(temp
));
1870 RuleBasedCollator
*collator
= getCollator(search
->collator
);
1871 StringSearch
*strsrch
= new StringSearch(pattern
, text
, collator
,
1873 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
1874 strsrch
->setAttribute(USEARCH_OVERLAP
, USEARCH_ON
, status
);
1875 if (U_FAILURE(status
) ||
1876 strsrch
->getAttribute(USEARCH_OVERLAP
) != USEARCH_ON
) {
1877 errln("Error setting overlap option");
1879 if (!assertEqualWithStringSearch(strsrch
, search
)) {
1883 search
= &(NONOVERLAPCANONICAL
[count
]);
1884 strsrch
->setAttribute(USEARCH_OVERLAP
, USEARCH_OFF
, status
);
1885 if (U_FAILURE(status
) ||
1886 strsrch
->getAttribute(USEARCH_OVERLAP
) != USEARCH_OFF
) {
1887 errln("Error setting overlap option");
1890 if (!assertEqualWithStringSearch(strsrch
, search
)) {
1892 errln("Error at test number %d", count
);
1900 void StringSearchTest::TestCollatorCanonical()
1902 /* test collator that thinks "o" and "p" are the same thing */
1904 u_unescape(COLLATORCANONICAL
[0].text
, temp
, 128);
1906 text
.setTo(temp
, u_strlen(temp
));
1907 u_unescape(COLLATORCANONICAL
[0].pattern
, temp
, 128);
1908 UnicodeString pattern
;
1909 pattern
.setTo(temp
, u_strlen(temp
));
1911 UErrorCode status
= U_ZERO_ERROR
;
1912 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
,
1914 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
1915 if (U_FAILURE(status
)) {
1916 errln("Error opening string search %s", u_errorName(status
));
1918 if (!assertEqualWithStringSearch(strsrch
, &COLLATORCANONICAL
[0])) {
1923 u_unescape(TESTCOLLATORRULE
, temp
, 128);
1924 UnicodeString rules
;
1925 rules
.setTo(temp
, u_strlen(temp
));
1926 RuleBasedCollator
*tailored
= new RuleBasedCollator(rules
,
1927 getECollationStrength(COLLATORCANONICAL
[1].strength
),
1930 if (U_FAILURE(status
)) {
1931 errln("Error opening rule based collator %s", u_errorName(status
));
1934 strsrch
->setCollator(tailored
, status
);
1935 if (U_FAILURE(status
) || *(strsrch
->getCollator()) != *tailored
) {
1936 errln("Error setting rule based collator");
1939 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
1940 if (!assertEqualWithStringSearch(strsrch
, &COLLATORCANONICAL
[1])) {
1942 if (tailored
!= NULL
) {
1949 strsrch
->setCollator(m_en_us_
, status
);
1951 if (U_FAILURE(status
) || *(strsrch
->getCollator()) != *m_en_us_
) {
1952 errln("Error setting rule based collator");
1954 if (!assertEqualWithStringSearch(strsrch
, &COLLATORCANONICAL
[0])) {
1957 if (tailored
!= NULL
) {
1962 void StringSearchTest::TestPatternCanonical()
1967 u_unescape(PATTERNCANONICAL
[0].text
, temp
, 128);
1969 text
.setTo(temp
, u_strlen(temp
));
1970 u_unescape(PATTERNCANONICAL
[0].pattern
, temp
, 128);
1971 UnicodeString pattern
;
1972 pattern
.setTo(temp
, u_strlen(temp
));
1974 m_en_us_
->setStrength(
1975 getECollationStrength(PATTERNCANONICAL
[0].strength
));
1977 UErrorCode status
= U_ZERO_ERROR
;
1978 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
, NULL
,
1980 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
1981 if (U_FAILURE(status
)) {
1982 errln("Error opening string search %s", u_errorName(status
));
1983 goto ENDTESTPATTERN
;
1985 if (pattern
!= strsrch
->getPattern()) {
1986 errln("Error setting pattern");
1988 if (!assertEqualWithStringSearch(strsrch
, &PATTERNCANONICAL
[0])) {
1989 goto ENDTESTPATTERN
;
1992 u_unescape(PATTERNCANONICAL
[1].pattern
, temp
, 128);
1993 pattern
.setTo(temp
, u_strlen(temp
));
1994 strsrch
->setPattern(pattern
, status
);
1995 if (pattern
!= strsrch
->getPattern()) {
1996 errln("Error setting pattern");
1997 goto ENDTESTPATTERN
;
2000 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
2001 if (U_FAILURE(status
)) {
2002 errln("Error setting pattern %s", u_errorName(status
));
2004 if (!assertEqualWithStringSearch(strsrch
, &PATTERNCANONICAL
[1])) {
2005 goto ENDTESTPATTERN
;
2008 u_unescape(PATTERNCANONICAL
[0].pattern
, temp
, 128);
2009 pattern
.setTo(temp
, u_strlen(temp
));
2010 strsrch
->setPattern(pattern
, status
);
2011 if (pattern
!= strsrch
->getPattern()) {
2012 errln("Error setting pattern");
2013 goto ENDTESTPATTERN
;
2016 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
2017 if (U_FAILURE(status
)) {
2018 errln("Error setting pattern %s", u_errorName(status
));
2020 if (!assertEqualWithStringSearch(strsrch
, &PATTERNCANONICAL
[0])) {
2021 goto ENDTESTPATTERN
;
2024 m_en_us_
->setStrength(getECollationStrength(UCOL_TERTIARY
));
2025 if (strsrch
!= NULL
) {
2030 void StringSearchTest::TestTextCanonical()
2033 u_unescape(TEXTCANONICAL
[0].text
, temp
, 128);
2035 text
.setTo(temp
, u_strlen(temp
));
2036 u_unescape(TEXTCANONICAL
[0].pattern
, temp
, 128);
2037 UnicodeString pattern
;
2038 pattern
.setTo(temp
, u_strlen(temp
));
2040 UErrorCode status
= U_ZERO_ERROR
;
2041 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
, NULL
,
2043 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
2045 if (U_FAILURE(status
)) {
2046 errln("Error opening string search %s", u_errorName(status
));
2047 goto ENDTESTPATTERN
;
2049 if (text
!= strsrch
->getText()) {
2050 errln("Error setting text");
2052 if (!assertEqualWithStringSearch(strsrch
, &TEXTCANONICAL
[0])) {
2053 goto ENDTESTPATTERN
;
2056 u_unescape(TEXTCANONICAL
[1].text
, temp
, 128);
2057 text
.setTo(temp
, u_strlen(temp
));
2058 strsrch
->setText(text
, status
);
2059 if (text
!= strsrch
->getText()) {
2060 errln("Error setting text");
2061 goto ENDTESTPATTERN
;
2063 if (U_FAILURE(status
)) {
2064 errln("Error setting text %s", u_errorName(status
));
2066 if (!assertEqualWithStringSearch(strsrch
, &TEXTCANONICAL
[1])) {
2067 goto ENDTESTPATTERN
;
2070 u_unescape(TEXTCANONICAL
[0].text
, temp
, 128);
2071 text
.setTo(temp
, u_strlen(temp
));
2072 strsrch
->setText(text
, status
);
2073 if (text
!= strsrch
->getText()) {
2074 errln("Error setting text");
2075 goto ENDTESTPATTERN
;
2077 if (U_FAILURE(status
)) {
2078 errln("Error setting pattern %s", u_errorName(status
));
2080 if (!assertEqualWithStringSearch(strsrch
, &TEXTCANONICAL
[0])) {
2081 goto ENDTESTPATTERN
;
2084 if (strsrch
!= NULL
) {
2089 void StringSearchTest::TestCompositeBoundariesCanonical()
2092 while (COMPOSITEBOUNDARIESCANONICAL
[count
].text
!= NULL
) {
2093 logln("composite %d", count
);
2094 if (!assertCanonicalEqual(&COMPOSITEBOUNDARIESCANONICAL
[count
])) {
2095 errln("Error at test number %d", count
);
2101 void StringSearchTest::TestGetSetOffsetCanonical()
2104 UErrorCode status
= U_ZERO_ERROR
;
2105 UnicodeString
text("text");
2106 UnicodeString
pattern("pattern");
2107 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
, NULL
,
2109 Collator
*collator
= strsrch
->getCollator();
2111 collator
->setAttribute(UCOL_NORMALIZATION_MODE
, UCOL_ON
, status
);
2113 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
2114 /* testing out of bounds error */
2115 strsrch
->setOffset(-1, status
);
2116 if (U_SUCCESS(status
)) {
2117 errln("Error expecting set offset error");
2119 strsrch
->setOffset(128, status
);
2120 if (U_SUCCESS(status
)) {
2121 errln("Error expecting set offset error");
2125 while (BASICCANONICAL
[index
].text
!= NULL
) {
2126 SearchData search
= BASICCANONICAL
[index
++];
2127 if (BASICCANONICAL
[index
].text
== NULL
) {
2128 /* skip the last one */
2132 u_unescape(search
.text
, temp
, 128);
2133 text
.setTo(temp
, u_strlen(temp
));
2134 u_unescape(search
.pattern
, temp
, 128);
2135 pattern
.setTo(temp
, u_strlen(temp
));
2137 UErrorCode status
= U_ZERO_ERROR
;
2138 strsrch
->setText(text
, status
);
2140 strsrch
->setPattern(pattern
, status
);
2143 int32_t matchindex
= search
.offset
[count
];
2144 while (U_SUCCESS(status
) && matchindex
>= 0) {
2145 int32_t matchlength
= search
.size
[count
];
2146 strsrch
->next(status
);
2147 if (matchindex
!= strsrch
->getMatchedStart() ||
2148 matchlength
!= strsrch
->getMatchedLength()) {
2149 char *str
= toCharString(strsrch
->getText());
2150 errln("Text: %s", str
);
2151 str
= toCharString(strsrch
->getPattern());
2152 errln("Pattern: %s", str
);
2153 errln("Error match found at %d %d",
2154 strsrch
->getMatchedStart(),
2155 strsrch
->getMatchedLength());
2158 matchindex
= search
.offset
[count
+ 1] == -1 ? -1 :
2159 search
.offset
[count
+ 2];
2160 if (search
.offset
[count
+ 1] != -1) {
2161 strsrch
->setOffset(search
.offset
[count
+ 1] + 1, status
);
2162 if (strsrch
->getOffset() != search
.offset
[count
+ 1] + 1) {
2163 errln("Error setting offset");
2170 strsrch
->next(status
);
2171 if (strsrch
->getMatchedStart() != USEARCH_DONE
) {
2172 char *str
= toCharString(strsrch
->getText());
2173 errln("Text: %s", str
);
2174 str
= toCharString(strsrch
->getPattern());
2175 errln("Pattern: %s", str
);
2176 errln("Error match found at %d %d", strsrch
->getMatchedStart(),
2177 strsrch
->getMatchedLength());
2183 collator
->setAttribute(UCOL_NORMALIZATION_MODE
, UCOL_OFF
, status
);
2187 void StringSearchTest::TestSupplementaryCanonical()
2190 while (SUPPLEMENTARYCANONICAL
[count
].text
!= NULL
) {
2191 if (!assertCanonicalEqual(&SUPPLEMENTARYCANONICAL
[count
])) {
2192 errln("Error at test number %d", count
);
2198 void StringSearchTest::TestContractionCanonical()
2202 u_unescape(CONTRACTIONRULE
, temp
, 128);
2203 UnicodeString rules
;
2204 rules
.setTo(temp
, u_strlen(temp
));
2206 UErrorCode status
= U_ZERO_ERROR
;
2207 RuleBasedCollator
*collator
= new RuleBasedCollator(rules
,
2208 getECollationStrength(UCOL_TERTIARY
), UCOL_ON
, status
);
2209 if (U_FAILURE(status
)) {
2210 errln("Error opening collator %s", u_errorName(status
));
2212 UnicodeString
text("text");
2213 UnicodeString
pattern("pattern");
2214 StringSearch
*strsrch
= new StringSearch(pattern
, text
, collator
, NULL
,
2216 strsrch
->setAttribute(USEARCH_CANONICAL_MATCH
, USEARCH_ON
, status
);
2217 if (U_FAILURE(status
)) {
2218 errln("Error opening string search %s", u_errorName(status
));
2222 while (CONTRACTIONCANONICAL
[count
].text
!= NULL
) {
2223 u_unescape(CONTRACTIONCANONICAL
[count
].text
, temp
, 128);
2224 text
.setTo(temp
, u_strlen(temp
));
2225 u_unescape(CONTRACTIONCANONICAL
[count
].pattern
, temp
, 128);
2226 pattern
.setTo(temp
, u_strlen(temp
));
2227 strsrch
->setText(text
, status
);
2228 strsrch
->setPattern(pattern
, status
);
2229 if (!assertEqualWithStringSearch(strsrch
,
2230 &CONTRACTIONCANONICAL
[count
])) {
2231 errln("Error at test number %d", count
);
2239 void StringSearchTest::TestUClassID()
2241 char id
= *((char *)StringSearch::getStaticClassID());
2243 errln("Static class id for StringSearch should be 0");
2245 UErrorCode status
= U_ZERO_ERROR
;
2246 UnicodeString
text("text");
2247 UnicodeString
pattern("pattern");
2248 StringSearch
*strsrch
= new StringSearch(pattern
, text
, m_en_us_
, NULL
,
2250 id
= *((char *)strsrch
->getDynamicClassID());
2252 errln("Dynamic class id for StringSearch should be 0");
2257 class TestSearch
: public SearchIterator
2260 TestSearch(const TestSearch
&obj
);
2261 TestSearch(const UnicodeString
&text
,
2262 BreakIterator
*breakiter
,
2263 const UnicodeString
&pattern
);
2266 void setOffset(int32_t position
, UErrorCode
&status
);
2267 int32_t getOffset() const;
2268 SearchIterator
* safeClone() const;
2272 * ICU "poor man's RTTI", returns a UClassID for the actual class.
2276 virtual inline UClassID
getDynamicClassID() const { return getStaticClassID(); }
2279 * ICU "poor man's RTTI", returns a UClassID for this class.
2283 static inline UClassID
getStaticClassID() { return (UClassID
)&fgClassID
; }
2285 UBool
operator!=(const TestSearch
&that
) const;
2287 UnicodeString m_pattern_
;
2290 int32_t handleNext(int32_t position
, UErrorCode
&status
);
2291 int32_t handlePrev(int32_t position
, UErrorCode
&status
);
2292 TestSearch
& operator=(const TestSearch
&that
);
2297 * The address of this static class variable serves as this class's ID
2298 * for ICU "poor man's RTTI".
2300 static const char fgClassID
;
2304 const char TestSearch::fgClassID
=0;
2306 TestSearch::TestSearch(const TestSearch
&obj
) : SearchIterator(obj
)
2308 m_offset_
= obj
.m_offset_
;
2309 m_pattern_
= obj
.m_pattern_
;
2312 TestSearch::TestSearch(const UnicodeString
&text
,
2313 BreakIterator
*breakiter
,
2314 const UnicodeString
&pattern
) : SearchIterator()
2316 m_breakiterator_
= breakiter
;
2317 m_pattern_
= pattern
;
2320 m_pattern_
= pattern
;
2323 TestSearch::~TestSearch()
2328 void TestSearch::setOffset(int32_t position
, UErrorCode
&status
)
2330 if (position
>= 0 && position
<= m_text_
.length()) {
2331 m_offset_
= position
;
2334 status
= U_INDEX_OUTOFBOUNDS_ERROR
;
2338 int32_t TestSearch::getOffset() const
2343 SearchIterator
* TestSearch::safeClone() const
2345 return new TestSearch(m_text_
, m_breakiterator_
, m_pattern_
);
2348 UBool
TestSearch::operator!=(const TestSearch
&that
) const
2350 if (SearchIterator::operator !=(that
)) {
2353 return m_offset_
!= that
.m_offset_
|| m_pattern_
!= that
.m_pattern_
;
2356 int32_t TestSearch::handleNext(int32_t start
, UErrorCode
&status
)
2358 if(U_SUCCESS(status
)) {
2359 int match
= m_text_
.indexOf(m_pattern_
, start
);
2361 m_offset_
= m_text_
.length();
2362 setMatchStart(m_offset_
);
2364 return USEARCH_DONE
;
2366 setMatchStart(match
);
2368 setMatchLength(m_pattern_
.length());
2371 return USEARCH_DONE
;
2375 int32_t TestSearch::handlePrev(int32_t start
, UErrorCode
&status
)
2377 if(U_SUCCESS(status
)) {
2378 int match
= m_text_
.lastIndexOf(m_pattern_
, 0, start
);
2381 setMatchStart(m_offset_
);
2383 return USEARCH_DONE
;
2385 setMatchStart(match
);
2387 setMatchLength(m_pattern_
.length());
2390 return USEARCH_DONE
;
2394 TestSearch
& TestSearch::operator=(const TestSearch
&that
)
2396 SearchIterator::operator=(that
);
2397 m_offset_
= that
.m_offset_
;
2398 m_pattern_
= that
.m_pattern_
;
2402 void StringSearchTest::TestSubclass()
2404 UnicodeString
text("abc abcd abc");
2405 UnicodeString
pattern("abc");
2406 TestSearch
search(text
, NULL
, pattern
);
2407 TestSearch
search2(search
);
2408 int expected
[] = {0, 4, 9};
2409 UErrorCode status
= U_ZERO_ERROR
;
2411 StringCharacterIterator
chariter(text
);
2413 search
.setText(text
, status
);
2414 if (search
.getText() != search2
.getText()) {
2415 errln("Error setting text");
2418 search
.setText(chariter
, status
);
2419 if (search
.getText() != search2
.getText()) {
2420 errln("Error setting text");
2424 // comparing constructors
2426 for (i
= 0; i
< UPRV_LENGTHOF(expected
); i
++) {
2427 if (search
.next(status
) != expected
[i
]) {
2428 errln("Error getting next match");
2430 if (search
.getMatchedLength() != search
.m_pattern_
.length()) {
2431 errln("Error getting next match length");
2434 if (search
.next(status
) != USEARCH_DONE
) {
2435 errln("Error should have reached the end of the iteration");
2437 for (i
= UPRV_LENGTHOF(expected
) - 1; i
>= 0; i
--) {
2438 if (search
.previous(status
) != expected
[i
]) {
2439 errln("Error getting previous match");
2441 if (search
.getMatchedLength() != search
.m_pattern_
.length()) {
2442 errln("Error getting previous match length");
2445 if (search
.previous(status
) != USEARCH_DONE
) {
2446 errln("Error should have reached the start of the iteration");
2450 class StubSearchIterator
:public SearchIterator
{
2452 StubSearchIterator(){}
2453 virtual void setOffset(int32_t , UErrorCode
&) {};
2454 virtual int32_t getOffset(void) const {return 0;};
2455 virtual SearchIterator
* safeClone(void) const {return NULL
;};
2456 virtual int32_t handleNext(int32_t , UErrorCode
&){return 0;};
2457 virtual int32_t handlePrev(int32_t , UErrorCode
&) {return 0;};
2458 virtual UClassID
getDynamicClassID() const {
2459 static char classID
= 0;
2460 return (UClassID
)&classID
;
2464 void StringSearchTest::TestCoverage(){
2465 StubSearchIterator stub1
, stub2
;
2466 UErrorCode status
= U_ZERO_ERROR
;
2468 if (stub1
!= stub2
){
2469 errln("new StubSearchIterator should be equal");
2472 stub2
.setText(UnicodeString("ABC"), status
);
2473 if (U_FAILURE(status
)) {
2474 errln("Error: SearchIterator::SetText");
2478 if (stub1
!= stub2
){
2479 errln("SearchIterator::operator = assigned object should be equal");
2483 #endif /* !UCONFIG_NO_BREAK_ITERATION */
2485 #endif /* #if !UCONFIG_NO_COLLATION */