1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
5 * Copyright (c) 1997-2009, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 ********************************************************************/
9 #include "unicode/utypes.h"
11 #if !UCONFIG_NO_COLLATION
13 #include "unicode/coll.h"
14 #include "unicode/tblcoll.h"
15 #include "unicode/unistr.h"
16 #include "unicode/sortkey.h"
25 #define MIN(x,y) ((x) < (y) ? (x) : (y))
29 #define MAX(x,y) ((x) > (y) ? (x) : (y))
32 CollationMonkeyTest::CollationMonkeyTest()
33 : source("-abcdefghijklmnopqrstuvwxyz#&^$@", ""),
36 UErrorCode status
= U_ZERO_ERROR
;
37 myCollator
= Collator::createInstance("en_US", status
);
40 CollationMonkeyTest::~CollationMonkeyTest()
47 CollationMonkeyTest::report(UnicodeString
& s
, UnicodeString
& t
, int32_t result
, int32_t revResult
)
49 if (revResult
!= -result
)
56 msg
+= " round trip comparison failed";
57 msg
+= (UnicodeString
) " (result " + result
+ ", reverse Result " + revResult
+ ")";
64 CollationMonkeyTest::checkValue(int32_t value
)
74 void CollationMonkeyTest::TestCollationKey(/* char* par */)
76 if(source
.length() == 0) {
77 errln(UNICODE_STRING("CollationMonkeyTest::TestCollationKey(): source is empty - ICU_DATA not set or data missing?", 92));
81 srand( (unsigned)time( NULL
) );
82 int32_t s
= checkValue(rand() % source
.length());
83 int32_t t
= checkValue(rand() % source
.length());
84 int32_t slen
= checkValue((rand() - source
.length()) % source
.length());
85 int32_t tlen
= checkValue((rand() - source
.length()) % source
.length());
86 UnicodeString subs
, subt
;
88 source
.extract(MIN(s
, slen
), MAX(s
, slen
), subs
);
89 source
.extract(MIN(t
, tlen
), MAX(t
, tlen
), subt
);
91 CollationKey collationKey1
, collationKey2
;
92 UErrorCode status1
= U_ZERO_ERROR
, status2
= U_ZERO_ERROR
;
94 myCollator
->setStrength(Collator::TERTIARY
);
95 myCollator
->getCollationKey(subs
, collationKey1
, status1
);
96 myCollator
->getCollationKey(subt
, collationKey2
, status2
);
97 int32_t result
= collationKey1
.compareTo(collationKey2
); // Tertiary
98 int32_t revResult
= collationKey2
.compareTo(collationKey1
); // Tertiary
99 report( subs
, subt
, result
, revResult
);
101 myCollator
->setStrength(Collator::SECONDARY
);
102 myCollator
->getCollationKey(subs
, collationKey1
, status1
);
103 myCollator
->getCollationKey(subt
, collationKey2
, status2
);
104 result
= collationKey1
.compareTo(collationKey2
); // Secondary
105 revResult
= collationKey2
.compareTo(collationKey1
); // Secondary
106 report( subs
, subt
, result
, revResult
);
108 myCollator
->setStrength(Collator::PRIMARY
);
109 myCollator
->getCollationKey(subs
, collationKey1
, status1
);
110 myCollator
->getCollationKey(subt
, collationKey2
, status2
);
111 result
= collationKey1
.compareTo(collationKey2
); // Primary
112 revResult
= collationKey2
.compareTo(collationKey1
); // Primary
113 report(subs
, subt
, result
, revResult
);
116 UnicodeString
addOne(subs
);
117 addOne
+= (UChar32
)0xE000;
119 myCollator
->getCollationKey(subs
, collationKey1
, status1
);
120 myCollator
->getCollationKey(addOne
, collationKey2
, status2
);
121 result
= collationKey1
.compareTo(collationKey2
);
124 msg
+= "CollationKey(";
126 msg
+= ") .LT. CollationKey(";
133 result
= collationKey2
.compareTo(collationKey1
);
136 msg
+= "CollationKey(";
138 msg
+= ") .GT. CollationKey(";
146 CollationMonkeyTest::TestCompare(/* char* par */)
148 if(source
.length() == 0) {
149 errln(UNICODE_STRING("CollationMonkeyTest::TestCompare(): source is empty - ICU_DATA not set or data missing?", 87));
153 /* Seed the random-number generator with current time so that
154 * the numbers will be different every time we run.
156 srand( (unsigned)time( NULL
) );
157 int32_t s
= checkValue(rand() % source
.length());
158 int32_t t
= checkValue(rand() % source
.length());
159 int32_t slen
= checkValue((rand() - source
.length()) % source
.length());
160 int32_t tlen
= checkValue((rand() - source
.length()) % source
.length());
161 UnicodeString subs
, subt
;
163 source
.extract(MIN(s
, slen
), MAX(s
, slen
), subs
);
164 source
.extract(MIN(t
, tlen
), MAX(t
, tlen
), subt
);
166 myCollator
->setStrength(Collator::TERTIARY
);
167 int32_t result
= myCollator
->compare(subs
, subt
); // Tertiary
168 int32_t revResult
= myCollator
->compare(subt
, subs
); // Tertiary
169 report(subs
, subt
, result
, revResult
);
171 myCollator
->setStrength(Collator::SECONDARY
);
172 result
= myCollator
->compare(subs
, subt
); // Secondary
173 revResult
= myCollator
->compare(subt
, subs
); // Secondary
174 report(subs
, subt
, result
, revResult
);
176 myCollator
->setStrength(Collator::PRIMARY
);
177 result
= myCollator
->compare(subs
, subt
); // Primary
178 revResult
= myCollator
->compare(subt
, subs
); // Primary
179 report(subs
, subt
, result
, revResult
);
182 UnicodeString
addOne(subs
);
183 addOne
+= (UChar32
)0xE000;
185 result
= myCollator
->compare(subs
, addOne
);
197 result
= myCollator
->compare(addOne
, subs
);
208 void CollationMonkeyTest::TestRules(/* char* par */){
209 UChar testSourceCases
[][10] = {
210 {0x0061, 0x0062, 0x007a, 0},
211 {0x0061, 0x0062, 0x007a, 0},
214 UChar testTargetCases
[][10] = {
215 {0x0061, 0x0062, 0x00e4, 0},
216 {0x0061, 0x0062, 0x0061, 0x0308, 0},
220 logln("Demo Test 1 : Create a new table collation with rules \"& z < 0x00e4\"");
221 UErrorCode status
= U_ZERO_ERROR
;
222 Collator
*col
= Collator::createInstance("en_US", status
);
223 const UnicodeString baseRules
= ((RuleBasedCollator
*)col
)->getRules();
224 UnicodeString
newRules(" & z < ");
225 newRules
.append((UChar
)0x00e4);
226 newRules
.insert(0, baseRules
);
227 RuleBasedCollator
*myCollation
= new RuleBasedCollator(newRules
, status
);
228 if (U_FAILURE(status
)) {
229 errln( "Demo Test 1 Table Collation object creation failed.");
233 doTest(myCollation
, testSourceCases
[i
], testTargetCases
[i
], Collator::LESS
);
237 logln("Demo Test 2 : Create a new table collation with rules \"& z < a 0x0308\"");
239 newRules
.append(" & z < a");
240 newRules
.append((UChar
)0x0308);
241 newRules
.insert(0, baseRules
);
242 myCollation
= new RuleBasedCollator(newRules
, status
);
243 if (U_FAILURE(status
)) {
244 errln( "Demo Test 1 Table Collation object creation failed.");
248 doTest(myCollation
, testSourceCases
[i
], testTargetCases
[i
], Collator::LESS
);
255 void CollationMonkeyTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
257 if (exec
) logln("TestSuite CollationMonkeyTest: ");
260 case 0: name
= "TestCompare"; if (exec
) TestCompare(/* par */); break;
261 case 1: name
= "TestCollationKey"; if (exec
) TestCollationKey(/* par */); break;
262 case 2: name
= "TestRules"; if (exec
) TestRules(/* par */); break;
263 default: name
= ""; break;
266 dataerrln("Class collator not instantiated");
271 #endif /* #if !UCONFIG_NO_COLLATION */