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