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