1// Copyright (C) 2016 and later: Unicode, Inc. and others. 2// License & terms of use: http://www.unicode.org/copyright.html 3/******************************************************************** 4 * COPYRIGHT: 5 * Copyright (c) 1997-2009, International Business Machines Corporation and 6 * others. All Rights Reserved. 7 ********************************************************************/ 8 9#include "unicode/utypes.h" 10 11#if !UCONFIG_NO_COLLATION 12 13#include "unicode/coll.h" 14#include "unicode/tblcoll.h" 15#include "unicode/unistr.h" 16#include "unicode/sortkey.h" 17#include "mnkytst.h" 18#include "sfwdchit.h" 19 20#include <stdlib.h> 21#include <stdio.h> 22#include <time.h> 23 24#ifndef MIN 25#define MIN(x,y) ((x) < (y) ? (x) : (y)) 26#endif 27 28#ifndef MAX 29#define MAX(x,y) ((x) > (y) ? (x) : (y)) 30#endif 31 32CollationMonkeyTest::CollationMonkeyTest() 33: source("-abcdefghijklmnopqrstuvwxyz#&^$@", ""), 34 myCollator(0) 35{ 36 UErrorCode status = U_ZERO_ERROR; 37 myCollator = Collator::createInstance("en_US", status); 38} 39 40CollationMonkeyTest::~CollationMonkeyTest() 41{ 42 delete myCollator; 43} 44 45 46void 47CollationMonkeyTest::report(UnicodeString& s, UnicodeString& t, int32_t result, int32_t revResult) 48{ 49 if (revResult != -result) 50 { 51 UnicodeString msg; 52 53 msg += s; 54 msg += " and "; 55 msg += t; 56 msg += " round trip comparison failed"; 57 msg += (UnicodeString) " (result " + result + ", reverse Result " + revResult + ")"; 58 59 errln(msg); 60 } 61} 62 63int32_t 64CollationMonkeyTest::checkValue(int32_t value) 65{ 66 if (value < 0) 67 { 68 return -value; 69 } 70 71 return value; 72} 73 74void CollationMonkeyTest::TestCollationKey(/* char* par */) 75{ 76 if(source.length() == 0) { 77 errln(UNICODE_STRING("CollationMonkeyTest::TestCollationKey(): source is empty - ICU_DATA not set or data missing?", 92)); 78 return; 79 } 80 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; 87 88 source.extract(MIN(s, slen), MAX(s, slen), subs); 89 source.extract(MIN(t, tlen), MAX(t, tlen), subt); 90 91 CollationKey collationKey1, collationKey2; 92 UErrorCode status1 = U_ZERO_ERROR, status2= U_ZERO_ERROR; 93 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); 100 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); 107 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); 114 115 UnicodeString msg; 116 UnicodeString addOne(subs); 117 addOne += (UChar32)0xE000; 118 119 myCollator->getCollationKey(subs, collationKey1, status1); 120 myCollator->getCollationKey(addOne, collationKey2, status2); 121 result = collationKey1.compareTo(collationKey2); 122 if (result != -1) 123 { 124 msg += "CollationKey("; 125 msg += subs; 126 msg += ") .LT. CollationKey("; 127 msg += addOne; 128 msg += ") Failed."; 129 errln(msg); 130 } 131 132 msg.remove(); 133 result = collationKey2.compareTo(collationKey1); 134 if (result != 1) 135 { 136 msg += "CollationKey("; 137 msg += addOne; 138 msg += ") .GT. CollationKey("; 139 msg += subs; 140 msg += ") Failed."; 141 errln(msg); 142 } 143} 144 145void 146CollationMonkeyTest::TestCompare(/* char* par */) 147{ 148 if(source.length() == 0) { 149 errln(UNICODE_STRING("CollationMonkeyTest::TestCompare(): source is empty - ICU_DATA not set or data missing?", 87)); 150 return; 151 } 152 153 /* Seed the random-number generator with current time so that 154 * the numbers will be different every time we run. 155 */ 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; 162 163 source.extract(MIN(s, slen), MAX(s, slen), subs); 164 source.extract(MIN(t, tlen), MAX(t, tlen), subt); 165 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); 170 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); 175 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); 180 181 UnicodeString msg; 182 UnicodeString addOne(subs); 183 addOne += (UChar32)0xE000; 184 185 result = myCollator->compare(subs, addOne); 186 if (result != -1) 187 { 188 msg += "Test : "; 189 msg += subs; 190 msg += " .LT. "; 191 msg += addOne; 192 msg += " Failed."; 193 errln(msg); 194 } 195 196 msg.remove(); 197 result = myCollator->compare(addOne, subs); 198 if (result != 1) 199 { 200 msg += "Test : "; 201 msg += addOne; 202 msg += " .GT. "; 203 msg += subs; 204 msg += " Failed."; 205 errln(msg); 206 } 207} 208void CollationMonkeyTest::TestRules(/* char* par */){ 209 UChar testSourceCases[][10] = { 210 {0x0061, 0x0062, 0x007a, 0}, 211 {0x0061, 0x0062, 0x007a, 0}, 212 }; 213 214 UChar testTargetCases[][10] = { 215 {0x0061, 0x0062, 0x00e4, 0}, 216 {0x0061, 0x0062, 0x0061, 0x0308, 0}, 217 }; 218 219 int i=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."); 230 return; 231 } 232 for(i=0; i<2; i++){ 233 doTest(myCollation, testSourceCases[i], testTargetCases[i], Collator::LESS); 234 } 235 delete myCollation; 236 237 logln("Demo Test 2 : Create a new table collation with rules \"& z < a 0x0308\""); 238 newRules.remove(); 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."); 245 return; 246 } 247 for(i=0; i<2; i++){ 248 doTest(myCollation, testSourceCases[i], testTargetCases[i], Collator::LESS); 249 } 250 delete myCollation; 251 delete col; 252 253} 254 255void CollationMonkeyTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) 256{ 257 if (exec) logln("TestSuite CollationMonkeyTest: "); 258 if(myCollator) { 259 switch (index) { 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; 264 } 265 } else { 266 dataerrln("Class collator not instantiated"); 267 name = ""; 268 } 269} 270 271#endif /* #if !UCONFIG_NO_COLLATION */ 272