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