1 /*
2 *****************************************************************************
3 * Copyright (C) 2001-2010, International Business Machines orporation
4 * and others. All Rights Reserved.
5 ****************************************************************************/
6
7 #include "unicode/utypes.h"
8
9 #if !UCONFIG_NO_COLLATION
10
11 #include "srchtest.h"
12 #include "../cintltst/usrchdat.c"
13 #include "unicode/stsearch.h"
14 #include "unicode/ustring.h"
15 #include "unicode/schriter.h"
16 #include <string.h>
17 #include <stdio.h>
18
19 // private definitions -----------------------------------------------------
20
21 #define CASE(id,test) \
22 case id: \
23 name = #test; \
24 if (exec) { \
25 logln(#test "---"); \
26 logln((UnicodeString)""); \
27 if(areBroken) { \
28 dataerrln(__FILE__ " cannot test - failed to create collator."); \
29 } else { \
30 test(); \
31 } \
32 } \
33 break;
34
35 // public contructors and destructors --------------------------------------
36
StringSearchTest()37 StringSearchTest::StringSearchTest()
38 #if !UCONFIG_NO_BREAK_ITERATION
39 :
40 m_en_wordbreaker_(NULL), m_en_characterbreaker_(NULL)
41 #endif
42 {
43 #if !UCONFIG_NO_BREAK_ITERATION
44 UErrorCode status = U_ZERO_ERROR;
45
46 m_en_us_ = (RuleBasedCollator *)Collator::createInstance("en_US", status);
47 m_fr_fr_ = (RuleBasedCollator *)Collator::createInstance("fr_FR", status);
48 m_de_ = (RuleBasedCollator *)Collator::createInstance("de_DE", status);
49 m_es_ = (RuleBasedCollator *)Collator::createInstance("es_ES", status);
50 if(U_FAILURE(status)) {
51 delete m_en_us_;
52 delete m_fr_fr_;
53 delete m_de_;
54 delete m_es_;
55 m_en_us_ = 0;
56 m_fr_fr_ = 0;
57 m_de_ = 0;
58 m_es_ = 0;
59 errln("Collator creation failed with %s", u_errorName(status));
60 return;
61 }
62
63
64 UnicodeString rules;
65 rules.setTo(((RuleBasedCollator *)m_de_)->getRules());
66 UChar extrarules[128];
67 u_unescape(EXTRACOLLATIONRULE, extrarules, 128);
68 rules.append(extrarules, u_strlen(extrarules));
69 delete m_de_;
70
71 m_de_ = new RuleBasedCollator(rules, status);
72
73 rules.setTo(((RuleBasedCollator *)m_es_)->getRules());
74 rules.append(extrarules, u_strlen(extrarules));
75
76 delete m_es_;
77
78 m_es_ = new RuleBasedCollator(rules, status);
79
80 #if !UCONFIG_NO_BREAK_ITERATION
81 m_en_wordbreaker_ = BreakIterator::createWordInstance(
82 Locale::getEnglish(), status);
83 m_en_characterbreaker_ = BreakIterator::createCharacterInstance(
84 Locale::getEnglish(), status);
85 #endif
86 #endif
87 }
88
~StringSearchTest()89 StringSearchTest::~StringSearchTest()
90 {
91 #if !UCONFIG_NO_BREAK_ITERATION
92 delete m_en_us_;
93 delete m_fr_fr_;
94 delete m_de_;
95 delete m_es_;
96 #if !UCONFIG_NO_BREAK_ITERATION
97 delete m_en_wordbreaker_;
98 delete m_en_characterbreaker_;
99 #endif
100 #endif
101 }
102
103 // public methods ----------------------------------------------------------
104
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)105 void StringSearchTest::runIndexedTest(int32_t index, UBool exec,
106 const char* &name, char* )
107 {
108 #if !UCONFIG_NO_BREAK_ITERATION
109 UBool areBroken = FALSE;
110 if (m_en_us_ == NULL && m_fr_fr_ == NULL && m_de_ == NULL &&
111 m_es_ == NULL && m_en_wordbreaker_ == NULL &&
112 m_en_characterbreaker_ == NULL && exec) {
113 areBroken = TRUE;
114 }
115
116 switch (index) {
117 #if !UCONFIG_NO_FILE_IO
118 CASE(0, TestOpenClose)
119 #endif
120 CASE(1, TestInitialization)
121 CASE(2, TestBasic)
122 CASE(3, TestNormExact)
123 CASE(4, TestStrength)
124 #if UCONFIG_NO_BREAK_ITERATION
125 case 5:
126 name = "TestBreakIterator";
127 break;
128 #else
129 CASE(5, TestBreakIterator)
130 #endif
131 CASE(6, TestVariable)
132 CASE(7, TestOverlap)
133 CASE(8, TestCollator)
134 CASE(9, TestPattern)
135 CASE(10, TestText)
136 CASE(11, TestCompositeBoundaries)
137 CASE(12, TestGetSetOffset)
138 CASE(13, TestGetSetAttribute)
139 CASE(14, TestGetMatch)
140 CASE(15, TestSetMatch)
141 CASE(16, TestReset)
142 CASE(17, TestSupplementary)
143 CASE(18, TestContraction)
144 CASE(19, TestIgnorable)
145 CASE(20, TestCanonical)
146 CASE(21, TestNormCanonical)
147 CASE(22, TestStrengthCanonical)
148 #if UCONFIG_NO_BREAK_ITERATION
149 case 23:
150 name = "TestBreakIteratorCanonical";
151 break;
152 #else
153 CASE(23, TestBreakIteratorCanonical)
154 #endif
155 CASE(24, TestVariableCanonical)
156 CASE(25, TestOverlapCanonical)
157 CASE(26, TestCollatorCanonical)
158 CASE(27, TestPatternCanonical)
159 CASE(28, TestTextCanonical)
160 CASE(29, TestCompositeBoundariesCanonical)
161 CASE(30, TestGetSetOffsetCanonical)
162 CASE(31, TestSupplementaryCanonical)
163 CASE(32, TestContractionCanonical)
164 CASE(33, TestUClassID)
165 CASE(34, TestSubclass)
166 CASE(35, TestCoverage)
167 CASE(36, TestDiacriticMatch)
168 default: name = ""; break;
169 }
170 #else
171 name="";
172 #endif
173 }
174
175 #if !UCONFIG_NO_BREAK_ITERATION
176 // private methods ------------------------------------------------------
177
getCollator(const char * collator)178 RuleBasedCollator * StringSearchTest::getCollator(const char *collator)
179 {
180 if (collator == NULL) {
181 return m_en_us_;
182 }
183 if (strcmp(collator, "fr") == 0) {
184 return m_fr_fr_;
185 }
186 else if (strcmp(collator, "de") == 0) {
187 return m_de_;
188 }
189 else if (strcmp(collator, "es") == 0) {
190 return m_es_;
191 }
192 else {
193 return m_en_us_;
194 }
195 }
196
getBreakIterator(const char * breaker)197 BreakIterator * StringSearchTest::getBreakIterator(const char *breaker)
198 {
199 #if UCONFIG_NO_BREAK_ITERATION
200 return NULL;
201 #else
202 if (breaker == NULL) {
203 return NULL;
204 }
205 if (strcmp(breaker, "wordbreaker") == 0) {
206 return m_en_wordbreaker_;
207 }
208 else {
209 return m_en_characterbreaker_;
210 }
211 #endif
212 }
213
toCharString(const UnicodeString & text)214 char * StringSearchTest::toCharString(const UnicodeString &text)
215 {
216 static char result[1024];
217 int index = 0;
218 int count = 0;
219 int length = text.length();
220
221 for (; count < length; count ++) {
222 UChar ch = text[count];
223 if (ch >= 0x20 && ch <= 0x7e) {
224 result[index ++] = (char)ch;
225 }
226 else {
227 sprintf(result+index, "\\u%04x", ch);
228 index += 6; /* \uxxxx */
229 }
230 }
231 result[index] = 0;
232
233 return result;
234 }
235
getECollationStrength(const UCollationStrength & strength) const236 Collator::ECollationStrength StringSearchTest::getECollationStrength(
237 const UCollationStrength &strength) const
238 {
239 switch (strength)
240 {
241 case UCOL_PRIMARY :
242 return Collator::PRIMARY;
243 case UCOL_SECONDARY :
244 return Collator::SECONDARY;
245 case UCOL_TERTIARY :
246 return Collator::TERTIARY;
247 default :
248 return Collator::IDENTICAL;
249 }
250 }
251
assertEqualWithStringSearch(StringSearch * strsrch,const SearchData * search)252 UBool StringSearchTest::assertEqualWithStringSearch(StringSearch *strsrch,
253 const SearchData *search)
254 {
255 int count = 0;
256 UErrorCode status = U_ZERO_ERROR;
257 int32_t matchindex = search->offset[count];
258 UnicodeString matchtext;
259
260 strsrch->setAttribute(USEARCH_ELEMENT_COMPARISON, search->elemCompare, status);
261 if (U_FAILURE(status)) {
262 errln("Error setting USEARCH_ELEMENT_COMPARISON attribute %s", u_errorName(status));
263 return FALSE;
264 }
265
266 if (strsrch->getMatchedStart() != USEARCH_DONE ||
267 strsrch->getMatchedLength() != 0) {
268 errln("Error with the initialization of match start and length");
269 }
270 // start of following matches
271 while (U_SUCCESS(status) && matchindex >= 0) {
272 int32_t matchlength = search->size[count];
273 strsrch->next(status);
274 if (matchindex != strsrch->getMatchedStart() ||
275 matchlength != strsrch->getMatchedLength()) {
276 char *str = toCharString(strsrch->getText());
277 errln("Text: %s", str);
278 str = toCharString(strsrch->getPattern());
279 infoln("Pattern: %s", str);
280 infoln("Error following match found at idx,len %d,%d; expected %d,%d",
281 strsrch->getMatchedStart(), strsrch->getMatchedLength(),
282 matchindex, matchlength);
283 return FALSE;
284 }
285 count ++;
286
287 strsrch->getMatchedText(matchtext);
288
289 if (U_FAILURE(status) ||
290 strsrch->getText().compareBetween(matchindex,
291 matchindex + matchlength,
292 matchtext, 0,
293 matchtext.length())) {
294 errln("Error getting following matched text");
295 }
296
297 matchindex = search->offset[count];
298 }
299 strsrch->next(status);
300 if (strsrch->getMatchedStart() != USEARCH_DONE ||
301 strsrch->getMatchedLength() != 0) {
302 char *str = toCharString(strsrch->getText());
303 errln("Text: %s", str);
304 str = toCharString(strsrch->getPattern());
305 errln("Pattern: %s", str);
306 errln("Error following match found at %d %d",
307 strsrch->getMatchedStart(), strsrch->getMatchedLength());
308 return FALSE;
309 }
310 // start of preceding matches
311 count = count == 0 ? 0 : count - 1;
312 matchindex = search->offset[count];
313 while (U_SUCCESS(status) && matchindex >= 0) {
314 int32_t matchlength = search->size[count];
315 strsrch->previous(status);
316 if (matchindex != strsrch->getMatchedStart() ||
317 matchlength != strsrch->getMatchedLength()) {
318 char *str = toCharString(strsrch->getText());
319 errln("Text: %s", str);
320 str = toCharString(strsrch->getPattern());
321 errln("Pattern: %s", str);
322 errln("Error following match found at %d %d",
323 strsrch->getMatchedStart(), strsrch->getMatchedLength());
324 return FALSE;
325 }
326
327 strsrch->getMatchedText(matchtext);
328
329 if (U_FAILURE(status) ||
330 strsrch->getText().compareBetween(matchindex,
331 matchindex + matchlength,
332 matchtext, 0,
333 matchtext.length())) {
334 errln("Error getting following matched text");
335 }
336
337 matchindex = count > 0 ? search->offset[count - 1] : -1;
338 count --;
339 }
340 strsrch->previous(status);
341 if (strsrch->getMatchedStart() != USEARCH_DONE ||
342 strsrch->getMatchedLength() != 0) {
343 char *str = toCharString(strsrch->getText());
344 errln("Text: %s", str);
345 str = toCharString(strsrch->getPattern());
346 errln("Pattern: %s", str);
347 errln("Error following match found at %d %d",
348 strsrch->getMatchedStart(), strsrch->getMatchedLength());
349 return FALSE;
350 }
351 strsrch->setAttribute(USEARCH_ELEMENT_COMPARISON, USEARCH_STANDARD_ELEMENT_COMPARISON, status);
352 return TRUE;
353 }
354
assertEqual(const SearchData * search)355 UBool StringSearchTest::assertEqual(const SearchData *search)
356 {
357 UErrorCode status = U_ZERO_ERROR;
358
359 Collator *collator = getCollator(search->collator);
360 BreakIterator *breaker = getBreakIterator(search->breaker);
361 StringSearch *strsrch, *strsrch2;
362 UChar temp[128];
363
364 #if UCONFIG_NO_BREAK_ITERATION
365 if(search->breaker) {
366 return TRUE; /* skip test */
367 }
368 #endif
369 u_unescape(search->text, temp, 128);
370 UnicodeString text;
371 text.setTo(temp);
372 u_unescape(search->pattern, temp, 128);
373 UnicodeString pattern;
374 pattern.setTo(temp);
375
376 #if !UCONFIG_NO_BREAK_ITERATION
377 if (breaker != NULL) {
378 breaker->setText(text);
379 }
380 #endif
381 collator->setStrength(getECollationStrength(search->strength));
382 strsrch = new StringSearch(pattern, text, (RuleBasedCollator *)collator,
383 breaker, status);
384 if (U_FAILURE(status)) {
385 errln("Error opening string search %s", u_errorName(status));
386 return FALSE;
387 }
388
389 if (!assertEqualWithStringSearch(strsrch, search)) {
390 collator->setStrength(getECollationStrength(UCOL_TERTIARY));
391 delete strsrch;
392 return FALSE;
393 }
394
395
396 strsrch2 = strsrch->clone();
397 if( strsrch2 == strsrch || *strsrch2 != *strsrch ||
398 !assertEqualWithStringSearch(strsrch2, search)
399 ) {
400 infoln("failure with StringSearch.clone()");
401 collator->setStrength(getECollationStrength(UCOL_TERTIARY));
402 delete strsrch;
403 delete strsrch2;
404 return FALSE;
405 }
406 delete strsrch2;
407
408 collator->setStrength(getECollationStrength(UCOL_TERTIARY));
409 delete strsrch;
410 return TRUE;
411 }
412
assertCanonicalEqual(const SearchData * search)413 UBool StringSearchTest::assertCanonicalEqual(const SearchData *search)
414 {
415 UErrorCode status = U_ZERO_ERROR;
416 Collator *collator = getCollator(search->collator);
417 BreakIterator *breaker = getBreakIterator(search->breaker);
418 StringSearch *strsrch;
419 UChar temp[128];
420 UBool result = TRUE;
421
422 #if UCONFIG_NO_BREAK_ITERATION
423 if(search->breaker) {
424 return TRUE; /* skip test */
425 }
426 #endif
427
428 u_unescape(search->text, temp, 128);
429 UnicodeString text;
430 text.setTo(temp);
431 u_unescape(search->pattern, temp, 128);
432 UnicodeString pattern;
433 pattern.setTo(temp);
434
435 #if !UCONFIG_NO_BREAK_ITERATION
436 if (breaker != NULL) {
437 breaker->setText(text);
438 }
439 #endif
440 collator->setStrength(getECollationStrength(search->strength));
441 collator->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status);
442 strsrch = new StringSearch(pattern, text, (RuleBasedCollator *)collator,
443 breaker, status);
444 strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
445 if (U_FAILURE(status)) {
446 errln("Error opening string search %s", u_errorName(status));
447 result = FALSE;
448 goto bail;
449 }
450
451 if (!assertEqualWithStringSearch(strsrch, search)) {
452 result = FALSE;
453 goto bail;
454 }
455
456 bail:
457 collator->setStrength(getECollationStrength(UCOL_TERTIARY));
458 collator->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_OFF, status);
459 delete strsrch;
460
461 return result;
462 }
463
assertEqualWithAttribute(const SearchData * search,USearchAttributeValue canonical,USearchAttributeValue overlap)464 UBool StringSearchTest::assertEqualWithAttribute(const SearchData *search,
465 USearchAttributeValue canonical,
466 USearchAttributeValue overlap)
467 {
468 UErrorCode status = U_ZERO_ERROR;
469 Collator *collator = getCollator(search->collator);
470 BreakIterator *breaker = getBreakIterator(search->breaker);
471 StringSearch *strsrch;
472 UChar temp[128];
473
474
475 #if UCONFIG_NO_BREAK_ITERATION
476 if(search->breaker) {
477 return TRUE; /* skip test */
478 }
479 #endif
480
481 u_unescape(search->text, temp, 128);
482 UnicodeString text;
483 text.setTo(temp);
484 u_unescape(search->pattern, temp, 128);
485 UnicodeString pattern;
486 pattern.setTo(temp);
487
488 #if !UCONFIG_NO_BREAK_ITERATION
489 if (breaker != NULL) {
490 breaker->setText(text);
491 }
492 #endif
493 collator->setStrength(getECollationStrength(search->strength));
494 strsrch = new StringSearch(pattern, text, (RuleBasedCollator *)collator,
495 breaker, status);
496 strsrch->setAttribute(USEARCH_CANONICAL_MATCH, canonical, status);
497 strsrch->setAttribute(USEARCH_OVERLAP, overlap, status);
498
499 if (U_FAILURE(status)) {
500 errln("Error opening string search %s", u_errorName(status));
501 return FALSE;
502 }
503
504 if (!assertEqualWithStringSearch(strsrch, search)) {
505 collator->setStrength(getECollationStrength(UCOL_TERTIARY));
506 delete strsrch;
507 return FALSE;
508 }
509 collator->setStrength(getECollationStrength(UCOL_TERTIARY));
510 delete strsrch;
511 return TRUE;
512 }
513
TestOpenClose()514 void StringSearchTest::TestOpenClose()
515 {
516 UErrorCode status = U_ZERO_ERROR;
517 StringSearch *result;
518 BreakIterator *breakiter = m_en_wordbreaker_;
519 UnicodeString pattern;
520 UnicodeString text;
521 UnicodeString temp("a");
522 StringCharacterIterator chariter(text);
523
524 /* testing null arguments */
525 result = new StringSearch(pattern, text, NULL, NULL, status);
526 if (U_SUCCESS(status)) {
527 errln("Error: NULL arguments should produce an error");
528 }
529 delete result;
530
531 chariter.setText(text);
532 status = U_ZERO_ERROR;
533 result = new StringSearch(pattern, chariter, NULL, NULL, status);
534 if (U_SUCCESS(status)) {
535 errln("Error: NULL arguments should produce an error");
536 }
537 delete result;
538
539 text.append(0, 0x1);
540 status = U_ZERO_ERROR;
541 result = new StringSearch(pattern, text, NULL, NULL, status);
542 if (U_SUCCESS(status)) {
543 errln("Error: Empty pattern should produce an error");
544 }
545 delete result;
546
547 chariter.setText(text);
548 status = U_ZERO_ERROR;
549 result = new StringSearch(pattern, chariter, NULL, NULL, status);
550 if (U_SUCCESS(status)) {
551 errln("Error: Empty pattern should produce an error");
552 }
553 delete result;
554
555 text.remove();
556 pattern.append(temp);
557 status = U_ZERO_ERROR;
558 result = new StringSearch(pattern, text, NULL, NULL, status);
559 if (U_SUCCESS(status)) {
560 errln("Error: Empty text should produce an error");
561 }
562 delete result;
563
564 chariter.setText(text);
565 status = U_ZERO_ERROR;
566 result = new StringSearch(pattern, chariter, NULL, NULL, status);
567 if (U_SUCCESS(status)) {
568 errln("Error: Empty text should produce an error");
569 }
570 delete result;
571
572 text.append(temp);
573 status = U_ZERO_ERROR;
574 result = new StringSearch(pattern, text, NULL, NULL, status);
575 if (U_SUCCESS(status)) {
576 errln("Error: NULL arguments should produce an error");
577 }
578 delete result;
579
580 chariter.setText(text);
581 status = U_ZERO_ERROR;
582 result = new StringSearch(pattern, chariter, NULL, NULL, status);
583 if (U_SUCCESS(status)) {
584 errln("Error: NULL arguments should produce an error");
585 }
586 delete result;
587
588 status = U_ZERO_ERROR;
589 result = new StringSearch(pattern, text, m_en_us_, NULL, status);
590 if (U_FAILURE(status)) {
591 errln("Error: NULL break iterator is valid for opening search");
592 }
593 delete result;
594
595 status = U_ZERO_ERROR;
596 result = new StringSearch(pattern, chariter, m_en_us_, NULL, status);
597 if (U_FAILURE(status)) {
598 errln("Error: NULL break iterator is valid for opening search");
599 }
600 delete result;
601
602 status = U_ZERO_ERROR;
603 result = new StringSearch(pattern, text, Locale::getEnglish(), NULL, status);
604 if (U_FAILURE(status) || result == NULL) {
605 errln("Error: NULL break iterator is valid for opening search");
606 }
607 delete result;
608
609 status = U_ZERO_ERROR;
610 result = new StringSearch(pattern, chariter, Locale::getEnglish(), NULL, status);
611 if (U_FAILURE(status)) {
612 errln("Error: NULL break iterator is valid for opening search");
613 }
614 delete result;
615
616 status = U_ZERO_ERROR;
617 result = new StringSearch(pattern, text, m_en_us_, breakiter, status);
618 if (U_FAILURE(status)) {
619 errln("Error: Break iterator is valid for opening search");
620 }
621 delete result;
622
623 status = U_ZERO_ERROR;
624 result = new StringSearch(pattern, chariter, m_en_us_, NULL, status);
625 if (U_FAILURE(status)) {
626 errln("Error: Break iterator is valid for opening search");
627 }
628 delete result;
629 }
630
TestInitialization()631 void StringSearchTest::TestInitialization()
632 {
633 UErrorCode status = U_ZERO_ERROR;
634 UnicodeString pattern;
635 UnicodeString text;
636 UnicodeString temp("a");
637 StringSearch *result;
638 int count;
639
640 /* simple test on the pattern ce construction */
641 pattern.append(temp);
642 pattern.append(temp);
643 text.append(temp);
644 text.append(temp);
645 text.append(temp);
646 result = new StringSearch(pattern, text, m_en_us_, NULL, status);
647 if (U_FAILURE(status)) {
648 errln("Error opening search %s", u_errorName(status));
649 }
650 StringSearch *copy = new StringSearch(*result);
651 if (*(copy->getCollator()) != *(result->getCollator()) ||
652 copy->getBreakIterator() != result->getBreakIterator() ||
653 copy->getMatchedLength() != result->getMatchedLength() ||
654 copy->getMatchedStart() != result->getMatchedStart() ||
655 copy->getOffset() != result->getOffset() ||
656 copy->getPattern() != result->getPattern() ||
657 copy->getText() != result->getText() ||
658 *(copy) != *(result))
659 {
660 errln("Error copying StringSearch");
661 }
662 delete copy;
663
664 copy = (StringSearch *)result->safeClone();
665 if (*(copy->getCollator()) != *(result->getCollator()) ||
666 copy->getBreakIterator() != result->getBreakIterator() ||
667 copy->getMatchedLength() != result->getMatchedLength() ||
668 copy->getMatchedStart() != result->getMatchedStart() ||
669 copy->getOffset() != result->getOffset() ||
670 copy->getPattern() != result->getPattern() ||
671 copy->getText() != result->getText() ||
672 *(copy) != *(result)) {
673 errln("Error copying StringSearch");
674 }
675 delete result;
676
677 /* testing if an extremely large pattern will fail the initialization */
678 for (count = 0; count < 512; count ++) {
679 pattern.append(temp);
680 }
681 result = new StringSearch(pattern, text, m_en_us_, NULL, status);
682 if (*result != *result) {
683 errln("Error: string search object expected to match itself");
684 }
685 if (*result == *copy) {
686 errln("Error: string search objects are not expected to match");
687 }
688 *copy = *result;
689 if (*(copy->getCollator()) != *(result->getCollator()) ||
690 copy->getBreakIterator() != result->getBreakIterator() ||
691 copy->getMatchedLength() != result->getMatchedLength() ||
692 copy->getMatchedStart() != result->getMatchedStart() ||
693 copy->getOffset() != result->getOffset() ||
694 copy->getPattern() != result->getPattern() ||
695 copy->getText() != result->getText() ||
696 *(copy) != *(result)) {
697 errln("Error copying StringSearch");
698 }
699 if (U_FAILURE(status)) {
700 errln("Error opening search %s", u_errorName(status));
701 }
702 delete result;
703 delete copy;
704 }
705
TestBasic()706 void StringSearchTest::TestBasic()
707 {
708 int count = 0;
709 while (BASIC[count].text != NULL) {
710 //printf("count %d", count);
711 if (!assertEqual(&BASIC[count])) {
712 infoln("Error at test number %d", count);
713 }
714 count ++;
715 }
716 }
717
TestNormExact()718 void StringSearchTest::TestNormExact()
719 {
720 int count = 0;
721 UErrorCode status = U_ZERO_ERROR;
722 m_en_us_->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status);
723 if (U_FAILURE(status)) {
724 errln("Error setting collation normalization %s",
725 u_errorName(status));
726 }
727 while (BASIC[count].text != NULL) {
728 if (!assertEqual(&BASIC[count])) {
729 infoln("Error at test number %d", count);
730 }
731 count ++;
732 }
733 count = 0;
734 while (NORMEXACT[count].text != NULL) {
735 if (!assertEqual(&NORMEXACT[count])) {
736 infoln("Error at test number %d", count);
737 }
738 count ++;
739 }
740 m_en_us_->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_OFF, status);
741 count = 0;
742 while (NONNORMEXACT[count].text != NULL) {
743 if (!assertEqual(&NONNORMEXACT[count])) {
744 infoln("Error at test number %d", count);
745 }
746 count ++;
747 }
748 }
749
TestStrength()750 void StringSearchTest::TestStrength()
751 {
752 int count = 0;
753 while (STRENGTH[count].text != NULL) {
754 if (!assertEqual(&STRENGTH[count])) {
755 infoln("Error at test number %d", count);
756 }
757 count ++;
758 }
759 }
760
761 #if !UCONFIG_NO_BREAK_ITERATION
762
TestBreakIterator()763 void StringSearchTest::TestBreakIterator()
764 {
765 UChar temp[128];
766 u_unescape(BREAKITERATOREXACT[0].text, temp, 128);
767 UnicodeString text;
768 text.setTo(temp, u_strlen(temp));
769 u_unescape(BREAKITERATOREXACT[0].pattern, temp, 128);
770 UnicodeString pattern;
771 pattern.setTo(temp, u_strlen(temp));
772
773 UErrorCode status = U_ZERO_ERROR;
774 StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL,
775 status);
776 if (U_FAILURE(status)) {
777 errln("Error opening string search %s", u_errorName(status));
778 }
779
780 strsrch->setBreakIterator(NULL, status);
781 if (U_FAILURE(status) || strsrch->getBreakIterator() != NULL) {
782 errln("Error usearch_getBreakIterator returned wrong object");
783 }
784
785 strsrch->setBreakIterator(m_en_characterbreaker_, status);
786 if (U_FAILURE(status) ||
787 strsrch->getBreakIterator() != m_en_characterbreaker_) {
788 errln("Error usearch_getBreakIterator returned wrong object");
789 }
790
791 strsrch->setBreakIterator(m_en_wordbreaker_, status);
792 if (U_FAILURE(status) ||
793 strsrch->getBreakIterator() != m_en_wordbreaker_) {
794 errln("Error usearch_getBreakIterator returned wrong object");
795 }
796
797 delete strsrch;
798
799 int count = 0;
800 while (count < 4) {
801 // special purposes for tests numbers 0-3
802 const SearchData *search = &(BREAKITERATOREXACT[count]);
803 RuleBasedCollator *collator = getCollator(search->collator);
804 BreakIterator *breaker = getBreakIterator(search->breaker);
805 StringSearch *strsrch;
806
807 u_unescape(search->text, temp, 128);
808 text.setTo(temp, u_strlen(temp));
809 u_unescape(search->pattern, temp, 128);
810 pattern.setTo(temp, u_strlen(temp));
811 if (breaker != NULL) {
812 breaker->setText(text);
813 }
814 collator->setStrength(getECollationStrength(search->strength));
815
816 strsrch = new StringSearch(pattern, text, collator, breaker, status);
817 if (U_FAILURE(status) ||
818 strsrch->getBreakIterator() != breaker) {
819 errln("Error setting break iterator");
820 if (strsrch != NULL) {
821 delete strsrch;
822 }
823 }
824 if (!assertEqualWithStringSearch(strsrch, search)) {
825 collator->setStrength(getECollationStrength(UCOL_TERTIARY));
826 delete strsrch;
827 }
828 search = &(BREAKITERATOREXACT[count + 1]);
829 breaker = getBreakIterator(search->breaker);
830 if (breaker != NULL) {
831 breaker->setText(text);
832 }
833 strsrch->setBreakIterator(breaker, status);
834 if (U_FAILURE(status) ||
835 strsrch->getBreakIterator() != breaker) {
836 errln("Error setting break iterator");
837 delete strsrch;
838 }
839 strsrch->reset();
840 if (!assertEqualWithStringSearch(strsrch, search)) {
841 infoln("Error at test number %d", count);
842 }
843 delete strsrch;
844 count += 2;
845 }
846 count = 0;
847 while (BREAKITERATOREXACT[count].text != NULL) {
848 if (!assertEqual(&BREAKITERATOREXACT[count])) {
849 infoln("Error at test number %d", count);
850 }
851 count ++;
852 }
853 }
854
855 #endif
856
TestVariable()857 void StringSearchTest::TestVariable()
858 {
859 int count = 0;
860 UErrorCode status = U_ZERO_ERROR;
861 m_en_us_->setAttribute(UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, status);
862 if (U_FAILURE(status)) {
863 errln("Error setting collation alternate attribute %s",
864 u_errorName(status));
865 }
866 while (VARIABLE[count].text != NULL) {
867 logln("variable %d", count);
868 if (!assertEqual(&VARIABLE[count])) {
869 infoln("Error at test number %d", count);
870 }
871 count ++;
872 }
873 m_en_us_->setAttribute(UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE,
874 status);
875 }
876
TestOverlap()877 void StringSearchTest::TestOverlap()
878 {
879 int count = 0;
880 while (OVERLAP[count].text != NULL) {
881 if (!assertEqualWithAttribute(&OVERLAP[count], USEARCH_OFF,
882 USEARCH_ON)) {
883 errln("Error at overlap test number %d", count);
884 }
885 count ++;
886 }
887 count = 0;
888 while (NONOVERLAP[count].text != NULL) {
889 if (!assertEqual(&NONOVERLAP[count])) {
890 errln("Error at non overlap test number %d", count);
891 }
892 count ++;
893 }
894
895 count = 0;
896 while (count < 1) {
897 const SearchData *search = &(OVERLAP[count]);
898 UChar temp[128];
899 u_unescape(search->text, temp, 128);
900 UnicodeString text;
901 text.setTo(temp, u_strlen(temp));
902 u_unescape(search->pattern, temp, 128);
903 UnicodeString pattern;
904 pattern.setTo(temp, u_strlen(temp));
905
906 RuleBasedCollator *collator = getCollator(search->collator);
907 UErrorCode status = U_ZERO_ERROR;
908 StringSearch *strsrch = new StringSearch(pattern, text,
909 collator, NULL,
910 status);
911
912 strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_ON, status);
913 if (U_FAILURE(status) ||
914 strsrch->getAttribute(USEARCH_OVERLAP) != USEARCH_ON) {
915 errln("Error setting overlap option");
916 }
917 if (!assertEqualWithStringSearch(strsrch, search)) {
918 delete strsrch;
919 return;
920 }
921
922 search = &(NONOVERLAP[count]);
923 strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_OFF, status);
924 if (U_FAILURE(status) ||
925 strsrch->getAttribute(USEARCH_OVERLAP) != USEARCH_OFF) {
926 errln("Error setting overlap option");
927 }
928 strsrch->reset();
929 if (!assertEqualWithStringSearch(strsrch, search)) {
930 delete strsrch;
931 errln("Error at test number %d", count);
932 }
933
934 count ++;
935 delete strsrch;
936 }
937 }
938
TestCollator()939 void StringSearchTest::TestCollator()
940 {
941 // test collator that thinks "o" and "p" are the same thing
942 UChar temp[128];
943 u_unescape(COLLATOR[0].text, temp, 128);
944 UnicodeString text;
945 text.setTo(temp, u_strlen(temp));
946 u_unescape(COLLATOR[0].pattern, temp, 128);
947 UnicodeString pattern;
948 pattern.setTo(temp, u_strlen(temp));
949
950 UErrorCode status = U_ZERO_ERROR;
951 StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL,
952 status);
953 if (U_FAILURE(status)) {
954 errln("Error opening string search %s", u_errorName(status));
955 delete strsrch;
956 return;
957 }
958 if (!assertEqualWithStringSearch(strsrch, &COLLATOR[0])) {
959 delete strsrch;
960 return;
961 }
962
963 u_unescape(TESTCOLLATORRULE, temp, 128);
964 UnicodeString rules;
965 rules.setTo(temp, u_strlen(temp));
966 RuleBasedCollator *tailored = new RuleBasedCollator(rules, status);
967 tailored->setStrength(getECollationStrength(COLLATOR[1].strength));
968
969 if (U_FAILURE(status)) {
970 errln("Error opening rule based collator %s", u_errorName(status));
971 delete strsrch;
972 if (tailored != NULL) {
973 delete tailored;
974 }
975 return;
976 }
977
978 strsrch->setCollator(tailored, status);
979 if (U_FAILURE(status) || (*strsrch->getCollator()) != (*tailored)) {
980 errln("Error setting rule based collator");
981 delete strsrch;
982 if (tailored != NULL) {
983 delete tailored;
984 }
985 }
986 strsrch->reset();
987 if (!assertEqualWithStringSearch(strsrch, &COLLATOR[1])) {
988 delete strsrch;
989 if (tailored != NULL) {
990 delete tailored;
991 }
992 return;
993 }
994
995 strsrch->setCollator(m_en_us_, status);
996 strsrch->reset();
997 if (U_FAILURE(status) || (*strsrch->getCollator()) != (*m_en_us_)) {
998 errln("Error setting rule based collator");
999 delete strsrch;
1000 if (tailored != NULL) {
1001 delete tailored;
1002 }
1003 }
1004 if (!assertEqualWithStringSearch(strsrch, &COLLATOR[0])) {
1005 errln("Error searching collator test");
1006 }
1007 delete strsrch;
1008 if (tailored != NULL) {
1009 delete tailored;
1010 }
1011 }
1012
TestPattern()1013 void StringSearchTest::TestPattern()
1014 {
1015
1016 UChar temp[512];
1017 int templength;
1018 u_unescape(PATTERN[0].text, temp, 512);
1019 UnicodeString text;
1020 text.setTo(temp, u_strlen(temp));
1021 u_unescape(PATTERN[0].pattern, temp, 512);
1022 UnicodeString pattern;
1023 pattern.setTo(temp, u_strlen(temp));
1024
1025 m_en_us_->setStrength(getECollationStrength(PATTERN[0].strength));
1026 UErrorCode status = U_ZERO_ERROR;
1027 StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL,
1028 status);
1029
1030 if (U_FAILURE(status)) {
1031 errln("Error opening string search %s", u_errorName(status));
1032 m_en_us_->setStrength(getECollationStrength(UCOL_TERTIARY));
1033 if (strsrch != NULL) {
1034 delete strsrch;
1035 }
1036 return;
1037 }
1038 if (strsrch->getPattern() != pattern) {
1039 errln("Error setting pattern");
1040 }
1041 if (!assertEqualWithStringSearch(strsrch, &PATTERN[0])) {
1042 m_en_us_->setStrength(getECollationStrength(UCOL_TERTIARY));
1043 if (strsrch != NULL) {
1044 delete strsrch;
1045 }
1046 return;
1047 }
1048
1049 u_unescape(PATTERN[1].pattern, temp, 512);
1050 pattern.setTo(temp, u_strlen(temp));
1051 strsrch->setPattern(pattern, status);
1052 if (pattern != strsrch->getPattern()) {
1053 errln("Error setting pattern");
1054 m_en_us_->setStrength(getECollationStrength(UCOL_TERTIARY));
1055 if (strsrch != NULL) {
1056 delete strsrch;
1057 }
1058 return;
1059 }
1060 strsrch->reset();
1061 if (U_FAILURE(status)) {
1062 errln("Error setting pattern %s", u_errorName(status));
1063 }
1064 if (!assertEqualWithStringSearch(strsrch, &PATTERN[1])) {
1065 m_en_us_->setStrength(getECollationStrength(UCOL_TERTIARY));
1066 if (strsrch != NULL) {
1067 delete strsrch;
1068 }
1069 return;
1070 }
1071
1072 u_unescape(PATTERN[0].pattern, temp, 512);
1073 pattern.setTo(temp, u_strlen(temp));
1074 strsrch->setPattern(pattern, status);
1075 if (pattern != strsrch->getPattern()) {
1076 errln("Error setting pattern");
1077 m_en_us_->setStrength(getECollationStrength(UCOL_TERTIARY));
1078 if (strsrch != NULL) {
1079 delete strsrch;
1080 }
1081 return;
1082 }
1083 strsrch->reset();
1084 if (U_FAILURE(status)) {
1085 errln("Error setting pattern %s", u_errorName(status));
1086 }
1087 if (!assertEqualWithStringSearch(strsrch, &PATTERN[0])) {
1088 m_en_us_->setStrength(getECollationStrength(UCOL_TERTIARY));
1089 if (strsrch != NULL) {
1090 delete strsrch;
1091 }
1092 return;
1093 }
1094 /* enormous pattern size to see if this crashes */
1095 for (templength = 0; templength != 512; templength ++) {
1096 temp[templength] = 0x61;
1097 }
1098 temp[511] = 0;
1099 pattern.setTo(temp, 511);
1100 strsrch->setPattern(pattern, status);
1101 if (U_FAILURE(status)) {
1102 errln("Error setting pattern with size 512, %s", u_errorName(status));
1103 }
1104 m_en_us_->setStrength(getECollationStrength(UCOL_TERTIARY));
1105 if (strsrch != NULL) {
1106 delete strsrch;
1107 }
1108 }
1109
TestText()1110 void StringSearchTest::TestText()
1111 {
1112 UChar temp[128];
1113 u_unescape(TEXT[0].text, temp, 128);
1114 UnicodeString text;
1115 text.setTo(temp, u_strlen(temp));
1116 u_unescape(TEXT[0].pattern, temp, 128);
1117 UnicodeString pattern;
1118 pattern.setTo(temp, u_strlen(temp));
1119
1120 UErrorCode status = U_ZERO_ERROR;
1121 StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL,
1122 status);
1123 if (U_FAILURE(status)) {
1124 errln("Error opening string search %s", u_errorName(status));
1125 return;
1126 }
1127 if (text != strsrch->getText()) {
1128 errln("Error setting text");
1129 }
1130 if (!assertEqualWithStringSearch(strsrch, &TEXT[0])) {
1131 delete strsrch;
1132 return;
1133 }
1134
1135 u_unescape(TEXT[1].text, temp, 128);
1136 text.setTo(temp, u_strlen(temp));
1137 strsrch->setText(text, status);
1138 if (text != strsrch->getText()) {
1139 errln("Error setting text");
1140 delete strsrch;
1141 return;
1142 }
1143 if (U_FAILURE(status)) {
1144 errln("Error setting text %s", u_errorName(status));
1145 }
1146 if (!assertEqualWithStringSearch(strsrch, &TEXT[1])) {
1147 delete strsrch;
1148 return;
1149 }
1150
1151 u_unescape(TEXT[0].text, temp, 128);
1152 text.setTo(temp, u_strlen(temp));
1153 StringCharacterIterator chariter(text);
1154 strsrch->setText(chariter, status);
1155 if (text != strsrch->getText()) {
1156 errln("Error setting text");
1157 delete strsrch;
1158 return;
1159 }
1160 if (U_FAILURE(status)) {
1161 errln("Error setting pattern %s", u_errorName(status));
1162 }
1163 if (!assertEqualWithStringSearch(strsrch, &TEXT[0])) {
1164 errln("Error searching within set text");
1165 }
1166 delete strsrch;
1167 }
1168
TestCompositeBoundaries()1169 void StringSearchTest::TestCompositeBoundaries()
1170 {
1171 int count = 0;
1172 while (COMPOSITEBOUNDARIES[count].text != NULL) {
1173 logln("composite %d", count);
1174 if (!assertEqual(&COMPOSITEBOUNDARIES[count])) {
1175 errln("Error at test number %d", count);
1176 }
1177 count ++;
1178 }
1179 }
1180
TestGetSetOffset()1181 void StringSearchTest::TestGetSetOffset()
1182 {
1183 UErrorCode status = U_ZERO_ERROR;
1184 UnicodeString pattern("1234567890123456");
1185 UnicodeString text("12345678901234567890123456789012");
1186 StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_,
1187 NULL, status);
1188 /* testing out of bounds error */
1189 strsrch->setOffset(-1, status);
1190 if (U_SUCCESS(status)) {
1191 errln("Error expecting set offset error");
1192 }
1193 strsrch->setOffset(128, status);
1194 if (U_SUCCESS(status)) {
1195 errln("Error expecting set offset error");
1196 }
1197 int index = 0;
1198 while (BASIC[index].text != NULL) {
1199 UErrorCode status = U_ZERO_ERROR;
1200 SearchData search = BASIC[index ++];
1201 UChar temp[128];
1202
1203 u_unescape(search.text, temp, 128);
1204 text.setTo(temp, u_strlen(temp));
1205 u_unescape(search.pattern, temp, 128);
1206 pattern.setTo(temp, u_strlen(temp));
1207 strsrch->setText(text, status);
1208 strsrch->setPattern(pattern, status);
1209 strsrch->getCollator()->setStrength(getECollationStrength(
1210 search.strength));
1211 strsrch->reset();
1212
1213 int count = 0;
1214 int32_t matchindex = search.offset[count];
1215 while (U_SUCCESS(status) && matchindex >= 0) {
1216 int32_t matchlength = search.size[count];
1217 strsrch->next(status);
1218 if (matchindex != strsrch->getMatchedStart() ||
1219 matchlength != strsrch->getMatchedLength()) {
1220 char *str = toCharString(strsrch->getText());
1221 errln("Text: %s", str);
1222 str = toCharString(strsrch->getPattern());
1223 errln("Pattern: %s", str);
1224 errln("Error match found at %d %d",
1225 strsrch->getMatchedStart(),
1226 strsrch->getMatchedLength());
1227 return;
1228 }
1229 matchindex = search.offset[count + 1] == -1 ? -1 :
1230 search.offset[count + 2];
1231 if (search.offset[count + 1] != -1) {
1232 strsrch->setOffset(search.offset[count + 1] + 1, status);
1233 if (strsrch->getOffset() != search.offset[count + 1] + 1) {
1234 errln("Error setting offset\n");
1235 return;
1236 }
1237 }
1238
1239 count += 2;
1240 }
1241 strsrch->next(status);
1242 if (strsrch->getMatchedStart() != USEARCH_DONE) {
1243 char *str = toCharString(strsrch->getText());
1244 errln("Text: %s", str);
1245 str = toCharString(strsrch->getPattern());
1246 errln("Pattern: %s", str);
1247 errln("Error match found at %d %d",
1248 strsrch->getMatchedStart(),
1249 strsrch->getMatchedLength());
1250 return;
1251 }
1252 }
1253 strsrch->getCollator()->setStrength(getECollationStrength(
1254 UCOL_TERTIARY));
1255 delete strsrch;
1256 }
1257
TestGetSetAttribute()1258 void StringSearchTest::TestGetSetAttribute()
1259 {
1260 UErrorCode status = U_ZERO_ERROR;
1261 UnicodeString pattern("pattern");
1262 UnicodeString text("text");
1263 StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL,
1264 status);
1265 if (U_FAILURE(status)) {
1266 errln("Error opening search %s", u_errorName(status));
1267 return;
1268 }
1269
1270 strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_DEFAULT, status);
1271 if (U_FAILURE(status) ||
1272 strsrch->getAttribute(USEARCH_OVERLAP) != USEARCH_OFF) {
1273 errln("Error setting overlap to the default");
1274 }
1275 strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_ON, status);
1276 if (U_FAILURE(status) ||
1277 strsrch->getAttribute(USEARCH_OVERLAP) != USEARCH_ON) {
1278 errln("Error setting overlap true");
1279 }
1280 strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_OFF, status);
1281 if (U_FAILURE(status) ||
1282 strsrch->getAttribute(USEARCH_OVERLAP) != USEARCH_OFF) {
1283 errln("Error setting overlap false");
1284 }
1285 strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_ATTRIBUTE_VALUE_COUNT,
1286 status);
1287 if (U_SUCCESS(status)) {
1288 errln("Error setting overlap to illegal value");
1289 }
1290 status = U_ZERO_ERROR;
1291 strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_DEFAULT, status);
1292 if (U_FAILURE(status) ||
1293 strsrch->getAttribute(USEARCH_CANONICAL_MATCH) != USEARCH_OFF) {
1294 errln("Error setting canonical match to the default");
1295 }
1296 strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
1297 if (U_FAILURE(status) ||
1298 strsrch->getAttribute(USEARCH_CANONICAL_MATCH) != USEARCH_ON) {
1299 errln("Error setting canonical match true");
1300 }
1301 strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_OFF, status);
1302 if (U_FAILURE(status) ||
1303 strsrch->getAttribute(USEARCH_CANONICAL_MATCH) != USEARCH_OFF) {
1304 errln("Error setting canonical match false");
1305 }
1306 strsrch->setAttribute(USEARCH_CANONICAL_MATCH,
1307 USEARCH_ATTRIBUTE_VALUE_COUNT, status);
1308 if (U_SUCCESS(status)) {
1309 errln("Error setting canonical match to illegal value");
1310 }
1311 status = U_ZERO_ERROR;
1312 strsrch->setAttribute(USEARCH_ATTRIBUTE_COUNT, USEARCH_DEFAULT, status);
1313 if (U_SUCCESS(status)) {
1314 errln("Error setting illegal attribute success");
1315 }
1316
1317 delete strsrch;
1318 }
1319
TestGetMatch()1320 void StringSearchTest::TestGetMatch()
1321 {
1322 UChar temp[128];
1323 SearchData search = MATCH[0];
1324 u_unescape(search.text, temp, 128);
1325 UnicodeString text;
1326 text.setTo(temp, u_strlen(temp));
1327 u_unescape(search.pattern, temp, 128);
1328 UnicodeString pattern;
1329 pattern.setTo(temp, u_strlen(temp));
1330
1331 UErrorCode status = U_ZERO_ERROR;
1332 StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL,
1333 status);
1334 if (U_FAILURE(status)) {
1335 errln("Error opening string search %s", u_errorName(status));
1336 if (strsrch != NULL) {
1337 delete strsrch;
1338 }
1339 return;
1340 }
1341
1342 int count = 0;
1343 int32_t matchindex = search.offset[count];
1344 UnicodeString matchtext;
1345 while (U_SUCCESS(status) && matchindex >= 0) {
1346 int32_t matchlength = search.size[count];
1347 strsrch->next(status);
1348 if (matchindex != strsrch->getMatchedStart() ||
1349 matchlength != strsrch->getMatchedLength()) {
1350 char *str = toCharString(strsrch->getText());
1351 errln("Text: %s", str);
1352 str = toCharString(strsrch->getPattern());
1353 errln("Pattern: %s", str);
1354 errln("Error match found at %d %d", strsrch->getMatchedStart(),
1355 strsrch->getMatchedLength());
1356 return;
1357 }
1358 count ++;
1359
1360 status = U_ZERO_ERROR;
1361 strsrch->getMatchedText(matchtext);
1362 if (matchtext.length() != matchlength || U_FAILURE(status)){
1363 errln("Error getting match text");
1364 }
1365 matchindex = search.offset[count];
1366 }
1367 status = U_ZERO_ERROR;
1368 strsrch->next(status);
1369 if (strsrch->getMatchedStart() != USEARCH_DONE ||
1370 strsrch->getMatchedLength() != 0) {
1371 errln("Error end of match not found");
1372 }
1373 status = U_ZERO_ERROR;
1374 strsrch->getMatchedText(matchtext);
1375 if (matchtext.length() != 0) {
1376 errln("Error getting null matches");
1377 }
1378 delete strsrch;
1379 }
1380
TestSetMatch()1381 void StringSearchTest::TestSetMatch()
1382 {
1383 int count = 0;
1384 while (MATCH[count].text != NULL) {
1385 SearchData search = MATCH[count];
1386 UChar temp[128];
1387 UErrorCode status = U_ZERO_ERROR;
1388 u_unescape(search.text, temp, 128);
1389 UnicodeString text;
1390 text.setTo(temp, u_strlen(temp));
1391 u_unescape(search.pattern, temp, 128);
1392 UnicodeString pattern;
1393 pattern.setTo(temp, u_strlen(temp));
1394
1395 StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_,
1396 NULL, status);
1397 if (U_FAILURE(status)) {
1398 errln("Error opening string search %s", u_errorName(status));
1399 if (strsrch != NULL) {
1400 delete strsrch;
1401 }
1402 return;
1403 }
1404
1405 int size = 0;
1406 while (search.offset[size] != -1) {
1407 size ++;
1408 }
1409
1410 if (strsrch->first(status) != search.offset[0] || U_FAILURE(status)) {
1411 errln("Error getting first match");
1412 }
1413 if (strsrch->last(status) != search.offset[size -1] ||
1414 U_FAILURE(status)) {
1415 errln("Error getting last match");
1416 }
1417
1418 int index = 0;
1419 while (index < size) {
1420 if (index + 2 < size) {
1421 if (strsrch->following(search.offset[index + 2] - 1, status)
1422 != search.offset[index + 2] || U_FAILURE(status)) {
1423 errln("Error getting following match at index %d",
1424 search.offset[index + 2] - 1);
1425 }
1426 }
1427 if (index + 1 < size) {
1428 if (strsrch->preceding(search.offset[index + 1] +
1429 search.size[index + 1] + 1,
1430 status) != search.offset[index + 1] ||
1431 U_FAILURE(status)) {
1432 errln("Error getting preceeding match at index %d",
1433 search.offset[index + 1] + 1);
1434 }
1435 }
1436 index += 2;
1437 }
1438 status = U_ZERO_ERROR;
1439 if (strsrch->following(text.length(), status) != USEARCH_DONE) {
1440 errln("Error expecting out of bounds match");
1441 }
1442 if (strsrch->preceding(0, status) != USEARCH_DONE) {
1443 errln("Error expecting out of bounds match");
1444 }
1445 count ++;
1446 delete strsrch;
1447 }
1448 }
1449
TestReset()1450 void StringSearchTest::TestReset()
1451 {
1452 UErrorCode status = U_ZERO_ERROR;
1453 UnicodeString text("fish fish");
1454 UnicodeString pattern("s");
1455 StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL,
1456 status);
1457 if (U_FAILURE(status)) {
1458 errln("Error opening string search %s", u_errorName(status));
1459 if (strsrch != NULL) {
1460 delete strsrch;
1461 }
1462 return;
1463 }
1464 strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_ON, status);
1465 strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
1466 strsrch->setOffset(9, status);
1467 if (U_FAILURE(status)) {
1468 errln("Error setting attributes and offsets");
1469 }
1470 else {
1471 strsrch->reset();
1472 if (strsrch->getAttribute(USEARCH_OVERLAP) != USEARCH_OFF ||
1473 strsrch->getAttribute(USEARCH_CANONICAL_MATCH) != USEARCH_OFF ||
1474 strsrch->getOffset() != 0 || strsrch->getMatchedLength() != 0 ||
1475 strsrch->getMatchedStart() != USEARCH_DONE) {
1476 errln("Error resetting string search");
1477 }
1478 strsrch->previous(status);
1479 if (strsrch->getMatchedStart() != 7 ||
1480 strsrch->getMatchedLength() != 1) {
1481 errln("Error resetting string search\n");
1482 }
1483 }
1484 delete strsrch;
1485 }
1486
TestSupplementary()1487 void StringSearchTest::TestSupplementary()
1488 {
1489 int count = 0;
1490 while (SUPPLEMENTARY[count].text != NULL) {
1491 if (!assertEqual(&SUPPLEMENTARY[count])) {
1492 errln("Error at test number %d", count);
1493 }
1494 count ++;
1495 }
1496 }
1497
TestContraction()1498 void StringSearchTest::TestContraction()
1499 {
1500 UChar temp[128];
1501 UErrorCode status = U_ZERO_ERROR;
1502
1503 u_unescape(CONTRACTIONRULE, temp, 128);
1504 UnicodeString rules;
1505 rules.setTo(temp, u_strlen(temp));
1506 RuleBasedCollator *collator = new RuleBasedCollator(rules,
1507 getECollationStrength(UCOL_TERTIARY), UCOL_ON, status);
1508 if (U_FAILURE(status)) {
1509 errln("Error opening collator %s", u_errorName(status));
1510 }
1511 UnicodeString text("text");
1512 UnicodeString pattern("pattern");
1513 StringSearch *strsrch = new StringSearch(pattern, text, collator, NULL,
1514 status);
1515 if (U_FAILURE(status)) {
1516 errln("Error opening string search %s", u_errorName(status));
1517 }
1518
1519 int count = 0;
1520 while (CONTRACTION[count].text != NULL) {
1521 u_unescape(CONTRACTION[count].text, temp, 128);
1522 text.setTo(temp, u_strlen(temp));
1523 u_unescape(CONTRACTION[count].pattern, temp, 128);
1524 pattern.setTo(temp, u_strlen(temp));
1525 strsrch->setText(text, status);
1526 strsrch->setPattern(pattern, status);
1527 if (!assertEqualWithStringSearch(strsrch, &CONTRACTION[count])) {
1528 errln("Error at test number %d", count);
1529 }
1530 count ++;
1531 }
1532 delete strsrch;
1533 delete collator;
1534 }
1535
TestIgnorable()1536 void StringSearchTest::TestIgnorable()
1537 {
1538 UChar temp[128];
1539 u_unescape(IGNORABLERULE, temp, 128);
1540 UnicodeString rules;
1541 rules.setTo(temp, u_strlen(temp));
1542 UErrorCode status = U_ZERO_ERROR;
1543 int count = 0;
1544 RuleBasedCollator *collator = new RuleBasedCollator(rules,
1545 getECollationStrength(IGNORABLE[count].strength),
1546 UCOL_ON, status);
1547 if (U_FAILURE(status)) {
1548 errln("Error opening collator %s", u_errorName(status));
1549 return;
1550 }
1551 UnicodeString pattern("pattern");
1552 UnicodeString text("text");
1553 StringSearch *strsrch = new StringSearch(pattern, text, collator, NULL,
1554 status);
1555 if (U_FAILURE(status)) {
1556 errln("Error opening string search %s", u_errorName(status));
1557 delete collator;
1558 return;
1559 }
1560
1561 while (IGNORABLE[count].text != NULL) {
1562 u_unescape(IGNORABLE[count].text, temp, 128);
1563 text.setTo(temp, u_strlen(temp));
1564 u_unescape(IGNORABLE[count].pattern, temp, 128);
1565 pattern.setTo(temp, u_strlen(temp));
1566 strsrch->setText(text, status);
1567 strsrch->setPattern(pattern, status);
1568 if (!assertEqualWithStringSearch(strsrch, &IGNORABLE[count])) {
1569 errln("Error at test number %d", count);
1570 }
1571 count ++;
1572 }
1573 delete strsrch;
1574 delete collator;
1575 }
1576
TestDiacriticMatch()1577 void StringSearchTest::TestDiacriticMatch()
1578 {
1579 UChar temp[128];
1580 UErrorCode status = U_ZERO_ERROR;
1581 int count = 0;
1582 RuleBasedCollator* coll = NULL;
1583 StringSearch *strsrch = NULL;
1584
1585 UnicodeString pattern("pattern");
1586 UnicodeString text("text");
1587
1588 const SearchData *search;
1589
1590 search = &(DIACRITICMATCH[count]);
1591 while (search->text != NULL) {
1592 coll = getCollator(search->collator);
1593 coll->setStrength(getECollationStrength(search->strength));
1594 strsrch = new StringSearch(pattern, text, coll, getBreakIterator(search->breaker), status);
1595 if (U_FAILURE(status)) {
1596 errln("Error opening string search %s", u_errorName(status));
1597 return;
1598 }
1599 u_unescape(search->text, temp, 128);
1600 text.setTo(temp, u_strlen(temp));
1601 u_unescape(search->pattern, temp, 128);
1602 pattern.setTo(temp, u_strlen(temp));
1603 strsrch->setText(text, status);
1604 strsrch->setPattern(pattern, status);
1605 if (!assertEqualWithStringSearch(strsrch, search)) {
1606 errln("Error at test number %d", count);
1607 }
1608 search = &(DIACRITICMATCH[++count]);
1609 delete strsrch;
1610 }
1611
1612 }
1613
TestCanonical()1614 void StringSearchTest::TestCanonical()
1615 {
1616 int count = 0;
1617 while (BASICCANONICAL[count].text != NULL) {
1618 if (!assertCanonicalEqual(&BASICCANONICAL[count])) {
1619 errln("Error at test number %d", count);
1620 }
1621 count ++;
1622 }
1623 }
1624
TestNormCanonical()1625 void StringSearchTest::TestNormCanonical()
1626 {
1627 UErrorCode status = U_ZERO_ERROR;
1628 m_en_us_->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status);
1629 int count = 0;
1630 while (NORMCANONICAL[count].text != NULL) {
1631 if (!assertCanonicalEqual(&NORMCANONICAL[count])) {
1632 errln("Error at test number %d", count);
1633 }
1634 count ++;
1635 }
1636 m_en_us_->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_OFF, status);
1637 }
1638
TestStrengthCanonical()1639 void StringSearchTest::TestStrengthCanonical()
1640 {
1641 int count = 0;
1642 while (STRENGTHCANONICAL[count].text != NULL) {
1643 if (!assertCanonicalEqual(&STRENGTHCANONICAL[count])) {
1644 errln("Error at test number %d", count);
1645 }
1646 count ++;
1647 }
1648 }
1649
1650 #if !UCONFIG_NO_BREAK_ITERATION
1651
TestBreakIteratorCanonical()1652 void StringSearchTest::TestBreakIteratorCanonical()
1653 {
1654 UErrorCode status = U_ZERO_ERROR;
1655 int count = 0;
1656
1657 while (count < 4) {
1658 // special purposes for tests numbers 0-3
1659 UChar temp[128];
1660 const SearchData *search = &(BREAKITERATORCANONICAL[count]);
1661
1662 u_unescape(search->text, temp, 128);
1663 UnicodeString text;
1664 text.setTo(temp, u_strlen(temp));
1665 u_unescape(search->pattern, temp, 128);
1666 UnicodeString pattern;
1667 pattern.setTo(temp, u_strlen(temp));
1668 RuleBasedCollator *collator = getCollator(search->collator);
1669 collator->setStrength(getECollationStrength(search->strength));
1670
1671 BreakIterator *breaker = getBreakIterator(search->breaker);
1672 StringSearch *strsrch = new StringSearch(pattern, text, collator,
1673 breaker, status);
1674 if (U_FAILURE(status)) {
1675 errln("Error creating string search data");
1676 return;
1677 }
1678 strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
1679 if (U_FAILURE(status) ||
1680 strsrch->getBreakIterator() != breaker) {
1681 errln("Error setting break iterator");
1682 delete strsrch;
1683 return;
1684 }
1685 if (!assertEqualWithStringSearch(strsrch, search)) {
1686 collator->setStrength(getECollationStrength(UCOL_TERTIARY));
1687 delete strsrch;
1688 return;
1689 }
1690 search = &(BREAKITERATOREXACT[count + 1]);
1691 breaker = getBreakIterator(search->breaker);
1692 if (breaker == NULL) {
1693 errln("Error creating BreakIterator");
1694 return;
1695 }
1696 breaker->setText(strsrch->getText());
1697 strsrch->setBreakIterator(breaker, status);
1698 if (U_FAILURE(status) || strsrch->getBreakIterator() != breaker) {
1699 errln("Error setting break iterator");
1700 delete strsrch;
1701 return;
1702 }
1703 strsrch->reset();
1704 strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
1705 if (!assertEqualWithStringSearch(strsrch, search)) {
1706 errln("Error at test number %d", count);
1707 return;
1708 }
1709 delete strsrch;
1710 count += 2;
1711 }
1712 count = 0;
1713 while (BREAKITERATORCANONICAL[count].text != NULL) {
1714 if (!assertEqual(&BREAKITERATORCANONICAL[count])) {
1715 errln("Error at test number %d", count);
1716 return;
1717 }
1718 count ++;
1719 }
1720 }
1721
1722 #endif
1723
TestVariableCanonical()1724 void StringSearchTest::TestVariableCanonical()
1725 {
1726 int count = 0;
1727 UErrorCode status = U_ZERO_ERROR;
1728 m_en_us_->setAttribute(UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, status);
1729 if (U_FAILURE(status)) {
1730 errln("Error setting collation alternate attribute %s",
1731 u_errorName(status));
1732 }
1733 while (VARIABLE[count].text != NULL) {
1734 logln("variable %d", count);
1735 if (!assertCanonicalEqual(&VARIABLE[count])) {
1736 errln("Error at test number %d", count);
1737 }
1738 count ++;
1739 }
1740 m_en_us_->setAttribute(UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE,
1741 status);
1742 }
1743
TestOverlapCanonical()1744 void StringSearchTest::TestOverlapCanonical()
1745 {
1746 int count = 0;
1747 while (OVERLAPCANONICAL[count].text != NULL) {
1748 if (!assertEqualWithAttribute(&OVERLAPCANONICAL[count], USEARCH_ON,
1749 USEARCH_ON)) {
1750 errln("Error at overlap test number %d", count);
1751 }
1752 count ++;
1753 }
1754 count = 0;
1755 while (NONOVERLAP[count].text != NULL) {
1756 if (!assertCanonicalEqual(&NONOVERLAPCANONICAL[count])) {
1757 errln("Error at non overlap test number %d", count);
1758 }
1759 count ++;
1760 }
1761
1762 count = 0;
1763 while (count < 1) {
1764 UChar temp[128];
1765 const SearchData *search = &(OVERLAPCANONICAL[count]);
1766 UErrorCode status = U_ZERO_ERROR;
1767
1768 u_unescape(search->text, temp, 128);
1769 UnicodeString text;
1770 text.setTo(temp, u_strlen(temp));
1771 u_unescape(search->pattern, temp, 128);
1772 UnicodeString pattern;
1773 pattern.setTo(temp, u_strlen(temp));
1774 RuleBasedCollator *collator = getCollator(search->collator);
1775 StringSearch *strsrch = new StringSearch(pattern, text, collator,
1776 NULL, status);
1777 strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
1778 strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_ON, status);
1779 if (U_FAILURE(status) ||
1780 strsrch->getAttribute(USEARCH_OVERLAP) != USEARCH_ON) {
1781 errln("Error setting overlap option");
1782 }
1783 if (!assertEqualWithStringSearch(strsrch, search)) {
1784 delete strsrch;
1785 return;
1786 }
1787 search = &(NONOVERLAPCANONICAL[count]);
1788 strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_OFF, status);
1789 if (U_FAILURE(status) ||
1790 strsrch->getAttribute(USEARCH_OVERLAP) != USEARCH_OFF) {
1791 errln("Error setting overlap option");
1792 }
1793 strsrch->reset();
1794 if (!assertEqualWithStringSearch(strsrch, search)) {
1795 delete strsrch;
1796 errln("Error at test number %d", count);
1797 }
1798
1799 count ++;
1800 delete strsrch;
1801 }
1802 }
1803
TestCollatorCanonical()1804 void StringSearchTest::TestCollatorCanonical()
1805 {
1806 /* test collator that thinks "o" and "p" are the same thing */
1807 UChar temp[128];
1808 u_unescape(COLLATORCANONICAL[0].text, temp, 128);
1809 UnicodeString text;
1810 text.setTo(temp, u_strlen(temp));
1811 u_unescape(COLLATORCANONICAL[0].pattern, temp, 128);
1812 UnicodeString pattern;
1813 pattern.setTo(temp, u_strlen(temp));
1814
1815 UErrorCode status = U_ZERO_ERROR;
1816 StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_,
1817 NULL, status);
1818 strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
1819 if (U_FAILURE(status)) {
1820 errln("Error opening string search %s", u_errorName(status));
1821 }
1822 if (!assertEqualWithStringSearch(strsrch, &COLLATORCANONICAL[0])) {
1823 delete strsrch;
1824 return;
1825 }
1826
1827 u_unescape(TESTCOLLATORRULE, temp, 128);
1828 UnicodeString rules;
1829 rules.setTo(temp, u_strlen(temp));
1830 RuleBasedCollator *tailored = new RuleBasedCollator(rules,
1831 getECollationStrength(COLLATORCANONICAL[1].strength),
1832 UCOL_ON, status);
1833
1834 if (U_FAILURE(status)) {
1835 errln("Error opening rule based collator %s", u_errorName(status));
1836 }
1837
1838 strsrch->setCollator(tailored, status);
1839 if (U_FAILURE(status) || *(strsrch->getCollator()) != *tailored) {
1840 errln("Error setting rule based collator");
1841 }
1842 strsrch->reset();
1843 strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
1844 if (!assertEqualWithStringSearch(strsrch, &COLLATORCANONICAL[1])) {
1845 delete strsrch;
1846 if (tailored != NULL) {
1847 delete tailored;
1848 }
1849
1850 return;
1851 }
1852
1853 strsrch->setCollator(m_en_us_, status);
1854 strsrch->reset();
1855 if (U_FAILURE(status) || *(strsrch->getCollator()) != *m_en_us_) {
1856 errln("Error setting rule based collator");
1857 }
1858 if (!assertEqualWithStringSearch(strsrch, &COLLATORCANONICAL[0])) {
1859 }
1860 delete strsrch;
1861 if (tailored != NULL) {
1862 delete tailored;
1863 }
1864 }
1865
TestPatternCanonical()1866 void StringSearchTest::TestPatternCanonical()
1867 {
1868
1869 UChar temp[128];
1870
1871 u_unescape(PATTERNCANONICAL[0].text, temp, 128);
1872 UnicodeString text;
1873 text.setTo(temp, u_strlen(temp));
1874 u_unescape(PATTERNCANONICAL[0].pattern, temp, 128);
1875 UnicodeString pattern;
1876 pattern.setTo(temp, u_strlen(temp));
1877
1878 m_en_us_->setStrength(
1879 getECollationStrength(PATTERNCANONICAL[0].strength));
1880
1881 UErrorCode status = U_ZERO_ERROR;
1882 StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL,
1883 status);
1884 strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
1885 if (U_FAILURE(status)) {
1886 errln("Error opening string search %s", u_errorName(status));
1887 goto ENDTESTPATTERN;
1888 }
1889 if (pattern != strsrch->getPattern()) {
1890 errln("Error setting pattern");
1891 }
1892 if (!assertEqualWithStringSearch(strsrch, &PATTERNCANONICAL[0])) {
1893 goto ENDTESTPATTERN;
1894 }
1895
1896 u_unescape(PATTERNCANONICAL[1].pattern, temp, 128);
1897 pattern.setTo(temp, u_strlen(temp));
1898 strsrch->setPattern(pattern, status);
1899 if (pattern != strsrch->getPattern()) {
1900 errln("Error setting pattern");
1901 goto ENDTESTPATTERN;
1902 }
1903 strsrch->reset();
1904 strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
1905 if (U_FAILURE(status)) {
1906 errln("Error setting pattern %s", u_errorName(status));
1907 }
1908 if (!assertEqualWithStringSearch(strsrch, &PATTERNCANONICAL[1])) {
1909 goto ENDTESTPATTERN;
1910 }
1911
1912 u_unescape(PATTERNCANONICAL[0].pattern, temp, 128);
1913 pattern.setTo(temp, u_strlen(temp));
1914 strsrch->setPattern(pattern, status);
1915 if (pattern != strsrch->getPattern()) {
1916 errln("Error setting pattern");
1917 goto ENDTESTPATTERN;
1918 }
1919 strsrch->reset();
1920 strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
1921 if (U_FAILURE(status)) {
1922 errln("Error setting pattern %s", u_errorName(status));
1923 }
1924 if (!assertEqualWithStringSearch(strsrch, &PATTERNCANONICAL[0])) {
1925 goto ENDTESTPATTERN;
1926 }
1927 ENDTESTPATTERN:
1928 m_en_us_->setStrength(getECollationStrength(UCOL_TERTIARY));
1929 if (strsrch != NULL) {
1930 delete strsrch;
1931 }
1932 }
1933
TestTextCanonical()1934 void StringSearchTest::TestTextCanonical()
1935 {
1936 UChar temp[128];
1937 u_unescape(TEXTCANONICAL[0].text, temp, 128);
1938 UnicodeString text;
1939 text.setTo(temp, u_strlen(temp));
1940 u_unescape(TEXTCANONICAL[0].pattern, temp, 128);
1941 UnicodeString pattern;
1942 pattern.setTo(temp, u_strlen(temp));
1943
1944 UErrorCode status = U_ZERO_ERROR;
1945 StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL,
1946 status);
1947 strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
1948
1949 if (U_FAILURE(status)) {
1950 errln("Error opening string search %s", u_errorName(status));
1951 goto ENDTESTPATTERN;
1952 }
1953 if (text != strsrch->getText()) {
1954 errln("Error setting text");
1955 }
1956 if (!assertEqualWithStringSearch(strsrch, &TEXTCANONICAL[0])) {
1957 goto ENDTESTPATTERN;
1958 }
1959
1960 u_unescape(TEXTCANONICAL[1].text, temp, 128);
1961 text.setTo(temp, u_strlen(temp));
1962 strsrch->setText(text, status);
1963 if (text != strsrch->getText()) {
1964 errln("Error setting text");
1965 goto ENDTESTPATTERN;
1966 }
1967 if (U_FAILURE(status)) {
1968 errln("Error setting text %s", u_errorName(status));
1969 }
1970 if (!assertEqualWithStringSearch(strsrch, &TEXTCANONICAL[1])) {
1971 goto ENDTESTPATTERN;
1972 }
1973
1974 u_unescape(TEXTCANONICAL[0].text, temp, 128);
1975 text.setTo(temp, u_strlen(temp));
1976 strsrch->setText(text, status);
1977 if (text != strsrch->getText()) {
1978 errln("Error setting text");
1979 goto ENDTESTPATTERN;
1980 }
1981 if (U_FAILURE(status)) {
1982 errln("Error setting pattern %s", u_errorName(status));
1983 }
1984 if (!assertEqualWithStringSearch(strsrch, &TEXTCANONICAL[0])) {
1985 goto ENDTESTPATTERN;
1986 }
1987 ENDTESTPATTERN:
1988 if (strsrch != NULL) {
1989 delete strsrch;
1990 }
1991 }
1992
TestCompositeBoundariesCanonical()1993 void StringSearchTest::TestCompositeBoundariesCanonical()
1994 {
1995 int count = 0;
1996 while (COMPOSITEBOUNDARIESCANONICAL[count].text != NULL) {
1997 logln("composite %d", count);
1998 if (!assertCanonicalEqual(&COMPOSITEBOUNDARIESCANONICAL[count])) {
1999 errln("Error at test number %d", count);
2000 }
2001 count ++;
2002 }
2003 }
2004
TestGetSetOffsetCanonical()2005 void StringSearchTest::TestGetSetOffsetCanonical()
2006 {
2007
2008 UErrorCode status = U_ZERO_ERROR;
2009 UnicodeString text("text");
2010 UnicodeString pattern("pattern");
2011 StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL,
2012 status);
2013 Collator *collator = strsrch->getCollator();
2014
2015 collator->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status);
2016
2017 strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
2018 /* testing out of bounds error */
2019 strsrch->setOffset(-1, status);
2020 if (U_SUCCESS(status)) {
2021 errln("Error expecting set offset error");
2022 }
2023 strsrch->setOffset(128, status);
2024 if (U_SUCCESS(status)) {
2025 errln("Error expecting set offset error");
2026 }
2027 int index = 0;
2028 UChar temp[128];
2029 while (BASICCANONICAL[index].text != NULL) {
2030 SearchData search = BASICCANONICAL[index ++];
2031 if (BASICCANONICAL[index].text == NULL) {
2032 /* skip the last one */
2033 break;
2034 }
2035
2036 u_unescape(search.text, temp, 128);
2037 text.setTo(temp, u_strlen(temp));
2038 u_unescape(search.pattern, temp, 128);
2039 pattern.setTo(temp, u_strlen(temp));
2040
2041 UErrorCode status = U_ZERO_ERROR;
2042 strsrch->setText(text, status);
2043
2044 strsrch->setPattern(pattern, status);
2045
2046 int count = 0;
2047 int32_t matchindex = search.offset[count];
2048 while (U_SUCCESS(status) && matchindex >= 0) {
2049 int32_t matchlength = search.size[count];
2050 strsrch->next(status);
2051 if (matchindex != strsrch->getMatchedStart() ||
2052 matchlength != strsrch->getMatchedLength()) {
2053 char *str = toCharString(strsrch->getText());
2054 errln("Text: %s", str);
2055 str = toCharString(strsrch->getPattern());
2056 errln("Pattern: %s", str);
2057 errln("Error match found at %d %d",
2058 strsrch->getMatchedStart(),
2059 strsrch->getMatchedLength());
2060 goto bail;
2061 }
2062 matchindex = search.offset[count + 1] == -1 ? -1 :
2063 search.offset[count + 2];
2064 if (search.offset[count + 1] != -1) {
2065 strsrch->setOffset(search.offset[count + 1] + 1, status);
2066 if (strsrch->getOffset() != search.offset[count + 1] + 1) {
2067 errln("Error setting offset");
2068 goto bail;
2069 }
2070 }
2071
2072 count += 2;
2073 }
2074 strsrch->next(status);
2075 if (strsrch->getMatchedStart() != USEARCH_DONE) {
2076 char *str = toCharString(strsrch->getText());
2077 errln("Text: %s", str);
2078 str = toCharString(strsrch->getPattern());
2079 errln("Pattern: %s", str);
2080 errln("Error match found at %d %d", strsrch->getMatchedStart(),
2081 strsrch->getMatchedLength());
2082 goto bail;
2083 }
2084 }
2085
2086 bail:
2087 collator->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_OFF, status);
2088 delete strsrch;
2089 }
2090
TestSupplementaryCanonical()2091 void StringSearchTest::TestSupplementaryCanonical()
2092 {
2093 int count = 0;
2094 while (SUPPLEMENTARYCANONICAL[count].text != NULL) {
2095 if (!assertCanonicalEqual(&SUPPLEMENTARYCANONICAL[count])) {
2096 errln("Error at test number %d", count);
2097 }
2098 count ++;
2099 }
2100 }
2101
TestContractionCanonical()2102 void StringSearchTest::TestContractionCanonical()
2103 {
2104 UChar temp[128];
2105
2106 u_unescape(CONTRACTIONRULE, temp, 128);
2107 UnicodeString rules;
2108 rules.setTo(temp, u_strlen(temp));
2109
2110 UErrorCode status = U_ZERO_ERROR;
2111 RuleBasedCollator *collator = new RuleBasedCollator(rules,
2112 getECollationStrength(UCOL_TERTIARY), UCOL_ON, status);
2113 if (U_FAILURE(status)) {
2114 errln("Error opening collator %s", u_errorName(status));
2115 }
2116 UnicodeString text("text");
2117 UnicodeString pattern("pattern");
2118 StringSearch *strsrch = new StringSearch(pattern, text, collator, NULL,
2119 status);
2120 strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
2121 if (U_FAILURE(status)) {
2122 errln("Error opening string search %s", u_errorName(status));
2123 }
2124
2125 int count = 0;
2126 while (CONTRACTIONCANONICAL[count].text != NULL) {
2127 u_unescape(CONTRACTIONCANONICAL[count].text, temp, 128);
2128 text.setTo(temp, u_strlen(temp));
2129 u_unescape(CONTRACTIONCANONICAL[count].pattern, temp, 128);
2130 pattern.setTo(temp, u_strlen(temp));
2131 strsrch->setText(text, status);
2132 strsrch->setPattern(pattern, status);
2133 if (!assertEqualWithStringSearch(strsrch,
2134 &CONTRACTIONCANONICAL[count])) {
2135 errln("Error at test number %d", count);
2136 }
2137 count ++;
2138 }
2139 delete strsrch;
2140 delete collator;
2141 }
2142
TestUClassID()2143 void StringSearchTest::TestUClassID()
2144 {
2145 char id = *((char *)StringSearch::getStaticClassID());
2146 if (id != 0) {
2147 errln("Static class id for StringSearch should be 0");
2148 }
2149 UErrorCode status = U_ZERO_ERROR;
2150 UnicodeString text("text");
2151 UnicodeString pattern("pattern");
2152 StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL,
2153 status);
2154 id = *((char *)strsrch->getDynamicClassID());
2155 if (id != 0) {
2156 errln("Dynamic class id for StringSearch should be 0");
2157 }
2158 delete strsrch;
2159 }
2160
2161 class TestSearch : public SearchIterator
2162 {
2163 public:
2164 TestSearch(const TestSearch &obj);
2165 TestSearch(const UnicodeString &text,
2166 BreakIterator *breakiter,
2167 const UnicodeString &pattern);
2168 ~TestSearch();
2169
2170 void setOffset(int32_t position, UErrorCode &status);
2171 int32_t getOffset() const;
2172 SearchIterator* safeClone() const;
2173
2174
2175 /**
2176 * ICU "poor man's RTTI", returns a UClassID for the actual class.
2177 *
2178 * @draft ICU 2.2
2179 */
getDynamicClassID() const2180 virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
2181
2182 /**
2183 * ICU "poor man's RTTI", returns a UClassID for this class.
2184 *
2185 * @draft ICU 2.2
2186 */
getStaticClassID()2187 static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
2188
2189 UBool operator!=(const TestSearch &that) const;
2190
2191 UnicodeString m_pattern_;
2192
2193 protected:
2194 int32_t handleNext(int32_t position, UErrorCode &status);
2195 int32_t handlePrev(int32_t position, UErrorCode &status);
2196 TestSearch & operator=(const TestSearch &that);
2197
2198 private:
2199
2200 /**
2201 * The address of this static class variable serves as this class's ID
2202 * for ICU "poor man's RTTI".
2203 */
2204 static const char fgClassID;
2205 uint32_t m_offset_;
2206 };
2207
2208 const char TestSearch::fgClassID=0;
2209
TestSearch(const TestSearch & obj)2210 TestSearch::TestSearch(const TestSearch &obj) : SearchIterator(obj)
2211 {
2212 m_offset_ = obj.m_offset_;
2213 m_pattern_ = obj.m_pattern_;
2214 }
2215
TestSearch(const UnicodeString & text,BreakIterator * breakiter,const UnicodeString & pattern)2216 TestSearch::TestSearch(const UnicodeString &text,
2217 BreakIterator *breakiter,
2218 const UnicodeString &pattern) : SearchIterator()
2219 {
2220 m_breakiterator_ = breakiter;
2221 m_pattern_ = pattern;
2222 m_text_ = text;
2223 m_offset_ = 0;
2224 m_pattern_ = pattern;
2225 }
2226
~TestSearch()2227 TestSearch::~TestSearch()
2228 {
2229 }
2230
2231
setOffset(int32_t position,UErrorCode & status)2232 void TestSearch::setOffset(int32_t position, UErrorCode &status)
2233 {
2234 if (position >= 0 && position <= m_text_.length()) {
2235 m_offset_ = position;
2236 }
2237 else {
2238 status = U_INDEX_OUTOFBOUNDS_ERROR;
2239 }
2240 }
2241
getOffset() const2242 int32_t TestSearch::getOffset() const
2243 {
2244 return m_offset_;
2245 }
2246
safeClone() const2247 SearchIterator * TestSearch::safeClone() const
2248 {
2249 return new TestSearch(m_text_, m_breakiterator_, m_pattern_);
2250 }
2251
operator !=(const TestSearch & that) const2252 UBool TestSearch::operator!=(const TestSearch &that) const
2253 {
2254 if (SearchIterator::operator !=(that)) {
2255 return FALSE;
2256 }
2257 return m_offset_ != that.m_offset_ || m_pattern_ != that.m_pattern_;
2258 }
2259
handleNext(int32_t start,UErrorCode & status)2260 int32_t TestSearch::handleNext(int32_t start, UErrorCode &status)
2261 {
2262 if(U_SUCCESS(status)) {
2263 int match = m_text_.indexOf(m_pattern_, start);
2264 if (match < 0) {
2265 m_offset_ = m_text_.length();
2266 setMatchStart(m_offset_);
2267 setMatchLength(0);
2268 return USEARCH_DONE;
2269 }
2270 setMatchStart(match);
2271 m_offset_ = match;
2272 setMatchLength(m_pattern_.length());
2273 return match;
2274 } else {
2275 return USEARCH_DONE;
2276 }
2277 }
2278
handlePrev(int32_t start,UErrorCode & status)2279 int32_t TestSearch::handlePrev(int32_t start, UErrorCode &status)
2280 {
2281 if(U_SUCCESS(status)) {
2282 int match = m_text_.lastIndexOf(m_pattern_, 0, start);
2283 if (match < 0) {
2284 m_offset_ = 0;
2285 setMatchStart(m_offset_);
2286 setMatchLength(0);
2287 return USEARCH_DONE;
2288 }
2289 setMatchStart(match);
2290 m_offset_ = match;
2291 setMatchLength(m_pattern_.length());
2292 return match;
2293 } else {
2294 return USEARCH_DONE;
2295 }
2296 }
2297
operator =(const TestSearch & that)2298 TestSearch & TestSearch::operator=(const TestSearch &that)
2299 {
2300 SearchIterator::operator=(that);
2301 m_offset_ = that.m_offset_;
2302 m_pattern_ = that.m_pattern_;
2303 return *this;
2304 }
2305
TestSubclass()2306 void StringSearchTest::TestSubclass()
2307 {
2308 UnicodeString text("abc abcd abc");
2309 UnicodeString pattern("abc");
2310 TestSearch search(text, NULL, pattern);
2311 TestSearch search2(search);
2312 int expected[] = {0, 4, 9};
2313 UErrorCode status = U_ZERO_ERROR;
2314 int i;
2315 StringCharacterIterator chariter(text);
2316
2317 search.setText(text, status);
2318 if (search.getText() != search2.getText()) {
2319 errln("Error setting text");
2320 }
2321
2322 search.setText(chariter, status);
2323 if (search.getText() != search2.getText()) {
2324 errln("Error setting text");
2325 }
2326
2327 search.reset();
2328 // comparing constructors
2329
2330 for (i = 0; i < (int)(sizeof(expected) / sizeof(expected[0])); i ++) {
2331 if (search.next(status) != expected[i]) {
2332 errln("Error getting next match");
2333 }
2334 if (search.getMatchedLength() != search.m_pattern_.length()) {
2335 errln("Error getting next match length");
2336 }
2337 }
2338 if (search.next(status) != USEARCH_DONE) {
2339 errln("Error should have reached the end of the iteration");
2340 }
2341 for (i = sizeof(expected) / sizeof(expected[0]) - 1; i >= 0; i --) {
2342 if (search.previous(status) != expected[i]) {
2343 errln("Error getting previous match");
2344 }
2345 if (search.getMatchedLength() != search.m_pattern_.length()) {
2346 errln("Error getting previous match length");
2347 }
2348 }
2349 if (search.previous(status) != USEARCH_DONE) {
2350 errln("Error should have reached the start of the iteration");
2351 }
2352 }
2353
2354 class StubSearchIterator:public SearchIterator{
2355 public:
StubSearchIterator()2356 StubSearchIterator(){}
setOffset(int32_t,UErrorCode &)2357 virtual void setOffset(int32_t , UErrorCode &) {};
getOffset(void) const2358 virtual int32_t getOffset(void) const {return 0;};
safeClone(void) const2359 virtual SearchIterator* safeClone(void) const {return NULL;};
handleNext(int32_t,UErrorCode &)2360 virtual int32_t handleNext(int32_t , UErrorCode &){return 0;};
handlePrev(int32_t,UErrorCode &)2361 virtual int32_t handlePrev(int32_t , UErrorCode &) {return 0;};
getDynamicClassID() const2362 virtual UClassID getDynamicClassID() const {
2363 static char classID = 0;
2364 return (UClassID)&classID;
2365 }
2366 };
2367
TestCoverage()2368 void StringSearchTest::TestCoverage(){
2369 StubSearchIterator stub1, stub2;
2370 UErrorCode status = U_ZERO_ERROR;
2371
2372 if (stub1 != stub2){
2373 errln("new StubSearchIterator should be equal");
2374 }
2375
2376 stub2.setText(UnicodeString("ABC"), status);
2377 if (U_FAILURE(status)) {
2378 errln("Error: SearchIterator::SetText");
2379 }
2380
2381 stub1 = stub2;
2382 if (stub1 != stub2){
2383 errln("SearchIterator::operator = assigned object should be equal");
2384 }
2385 }
2386
2387 #endif /* !UCONFIG_NO_BREAK_ITERATION */
2388
2389 #endif /* #if !UCONFIG_NO_COLLATION */
2390