1 /******************************************************************** 2 * COPYRIGHT: 3 * Copyright (c) 1997-2009, International Business Machines Corporation and 4 * others. All Rights Reserved. 5 ********************************************************************/ 6 7 #include "unicode/utypes.h" 8 9 #if !UCONFIG_NO_COLLATION 10 11 #include "unicode/coll.h" 12 #include "unicode/tblcoll.h" 13 #include "unicode/unistr.h" 14 #include "unicode/sortkey.h" 15 #include "mnkytst.h" 16 #include "sfwdchit.h" 17 18 #include <stdlib.h> 19 #include <stdio.h> 20 #include <time.h> 21 22 #ifndef MIN 23 #define MIN(x,y) ((x) < (y) ? (x) : (y)) 24 #endif 25 26 #ifndef MAX 27 #define MAX(x,y) ((x) > (y) ? (x) : (y)) 28 #endif 29 30 CollationMonkeyTest::CollationMonkeyTest() 31 : source("-abcdefghijklmnopqrstuvwxyz#&^$@", ""), 32 myCollator(0) 33 { 34 UErrorCode status = U_ZERO_ERROR; 35 myCollator = Collator::createInstance("en_US", status); 36 } 37 38 CollationMonkeyTest::~CollationMonkeyTest() 39 { 40 delete myCollator; 41 } 42 43 44 void 45 CollationMonkeyTest::report(UnicodeString& s, UnicodeString& t, int32_t result, int32_t revResult) 46 { 47 if (revResult != -result) 48 { 49 UnicodeString msg; 50 51 msg += s; 52 msg += " and "; 53 msg += t; 54 msg += " round trip comparison failed"; 55 msg += (UnicodeString) " (result " + result + ", reverse Result " + revResult + ")"; 56 57 errln(msg); 58 } 59 } 60 61 int32_t 62 CollationMonkeyTest::checkValue(int32_t value) 63 { 64 if (value < 0) 65 { 66 return -value; 67 } 68 69 return value; 70 } 71 72 void CollationMonkeyTest::TestCollationKey(/* char* par */) 73 { 74 if(source.length() == 0) { 75 errln(UNICODE_STRING("CollationMonkeyTest::TestCollationKey(): source is empty - ICU_DATA not set or data missing?", 92)); 76 return; 77 } 78 79 srand( (unsigned)time( NULL ) ); 80 int32_t s = checkValue(rand() % source.length()); 81 int32_t t = checkValue(rand() % source.length()); 82 int32_t slen = checkValue((rand() - source.length()) % source.length()); 83 int32_t tlen = checkValue((rand() - source.length()) % source.length()); 84 UnicodeString subs, subt; 85 86 source.extract(MIN(s, slen), MAX(s, slen), subs); 87 source.extract(MIN(t, tlen), MAX(t, tlen), subt); 88 89 CollationKey collationKey1, collationKey2; 90 UErrorCode status1 = U_ZERO_ERROR, status2= U_ZERO_ERROR; 91 92 myCollator->setStrength(Collator::TERTIARY); 93 myCollator->getCollationKey(subs, collationKey1, status1); 94 myCollator->getCollationKey(subt, collationKey2, status2); 95 int32_t result = collationKey1.compareTo(collationKey2); // Tertiary 96 int32_t revResult = collationKey2.compareTo(collationKey1); // Tertiary 97 report( subs, subt, result, revResult); 98 99 myCollator->setStrength(Collator::SECONDARY); 100 myCollator->getCollationKey(subs, collationKey1, status1); 101 myCollator->getCollationKey(subt, collationKey2, status2); 102 result = collationKey1.compareTo(collationKey2); // Secondary 103 revResult = collationKey2.compareTo(collationKey1); // Secondary 104 report( subs, subt, result, revResult); 105 106 myCollator->setStrength(Collator::PRIMARY); 107 myCollator->getCollationKey(subs, collationKey1, status1); 108 myCollator->getCollationKey(subt, collationKey2, status2); 109 result = collationKey1.compareTo(collationKey2); // Primary 110 revResult = collationKey2.compareTo(collationKey1); // Primary 111 report(subs, subt, result, revResult); 112 113 UnicodeString msg; 114 UnicodeString addOne(subs); 115 addOne += (UChar32)0xE000; 116 117 myCollator->getCollationKey(subs, collationKey1, status1); 118 myCollator->getCollationKey(addOne, collationKey2, status2); 119 result = collationKey1.compareTo(collationKey2); 120 if (result != -1) 121 { 122 msg += "CollationKey("; 123 msg += subs; 124 msg += ") .LT. CollationKey("; 125 msg += addOne; 126 msg += ") Failed."; 127 errln(msg); 128 } 129 130 msg.remove(); 131 result = collationKey2.compareTo(collationKey1); 132 if (result != 1) 133 { 134 msg += "CollationKey("; 135 msg += addOne; 136 msg += ") .GT. CollationKey("; 137 msg += subs; 138 msg += ") Failed."; 139 errln(msg); 140 } 141 } 142 143 void 144 CollationMonkeyTest::TestCompare(/* char* par */) 145 { 146 if(source.length() == 0) { 147 errln(UNICODE_STRING("CollationMonkeyTest::TestCompare(): source is empty - ICU_DATA not set or data missing?", 87)); 148 return; 149 } 150 151 /* Seed the random-number generator with current time so that 152 * the numbers will be different every time we run. 153 */ 154 srand( (unsigned)time( NULL ) ); 155 int32_t s = checkValue(rand() % source.length()); 156 int32_t t = checkValue(rand() % source.length()); 157 int32_t slen = checkValue((rand() - source.length()) % source.length()); 158 int32_t tlen = checkValue((rand() - source.length()) % source.length()); 159 UnicodeString subs, subt; 160 161 source.extract(MIN(s, slen), MAX(s, slen), subs); 162 source.extract(MIN(t, tlen), MAX(t, tlen), subt); 163 164 myCollator->setStrength(Collator::TERTIARY); 165 int32_t result = myCollator->compare(subs, subt); // Tertiary 166 int32_t revResult = myCollator->compare(subt, subs); // Tertiary 167 report(subs, subt, result, revResult); 168 169 myCollator->setStrength(Collator::SECONDARY); 170 result = myCollator->compare(subs, subt); // Secondary 171 revResult = myCollator->compare(subt, subs); // Secondary 172 report(subs, subt, result, revResult); 173 174 myCollator->setStrength(Collator::PRIMARY); 175 result = myCollator->compare(subs, subt); // Primary 176 revResult = myCollator->compare(subt, subs); // Primary 177 report(subs, subt, result, revResult); 178 179 UnicodeString msg; 180 UnicodeString addOne(subs); 181 addOne += (UChar32)0xE000; 182 183 result = myCollator->compare(subs, addOne); 184 if (result != -1) 185 { 186 msg += "Test : "; 187 msg += subs; 188 msg += " .LT. "; 189 msg += addOne; 190 msg += " Failed."; 191 errln(msg); 192 } 193 194 msg.remove(); 195 result = myCollator->compare(addOne, subs); 196 if (result != 1) 197 { 198 msg += "Test : "; 199 msg += addOne; 200 msg += " .GT. "; 201 msg += subs; 202 msg += " Failed."; 203 errln(msg); 204 } 205 } 206 void CollationMonkeyTest::TestRules(/* char* par */){ 207 UChar testSourceCases[][10] = { 208 {0x0061, 0x0062, 0x007a, 0}, 209 {0x0061, 0x0062, 0x007a, 0}, 210 }; 211 212 UChar testTargetCases[][10] = { 213 {0x0061, 0x0062, 0x00e4, 0}, 214 {0x0061, 0x0062, 0x0061, 0x0308, 0}, 215 }; 216 217 int i=0; 218 logln("Demo Test 1 : Create a new table collation with rules \"& z < 0x00e4\""); 219 UErrorCode status = U_ZERO_ERROR; 220 Collator *col = Collator::createInstance("en_US", status); 221 const UnicodeString baseRules = ((RuleBasedCollator*)col)->getRules(); 222 UnicodeString newRules(" & z < "); 223 newRules.append((UChar)0x00e4); 224 newRules.insert(0, baseRules); 225 RuleBasedCollator *myCollation = new RuleBasedCollator(newRules, status); 226 if (U_FAILURE(status)) { 227 errln( "Demo Test 1 Table Collation object creation failed."); 228 return; 229 } 230 for(i=0; i<2; i++){ 231 doTest(myCollation, testSourceCases[i], testTargetCases[i], Collator::LESS); 232 } 233 delete myCollation; 234 235 logln("Demo Test 2 : Create a new table collation with rules \"& z < a 0x0308\""); 236 newRules.remove(); 237 newRules.append(" & z < a"); 238 newRules.append((UChar)0x0308); 239 newRules.insert(0, baseRules); 240 myCollation = new RuleBasedCollator(newRules, status); 241 if (U_FAILURE(status)) { 242 errln( "Demo Test 1 Table Collation object creation failed."); 243 return; 244 } 245 for(i=0; i<2; i++){ 246 doTest(myCollation, testSourceCases[i], testTargetCases[i], Collator::LESS); 247 } 248 delete myCollation; 249 delete col; 250 251 } 252 253 void CollationMonkeyTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) 254 { 255 if (exec) logln("TestSuite CollationMonkeyTest: "); 256 if(myCollator) { 257 switch (index) { 258 case 0: name = "TestCompare"; if (exec) TestCompare(/* par */); break; 259 case 1: name = "TestCollationKey"; if (exec) TestCollationKey(/* par */); break; 260 case 2: name = "TestRules"; if (exec) TestRules(/* par */); break; 261 default: name = ""; break; 262 } 263 } else { 264 dataerrln("Class collator not instantiated"); 265 name = ""; 266 } 267 } 268 269 #endif /* #if !UCONFIG_NO_COLLATION */ 270