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