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