1// © 2016 and later: Unicode, Inc. and others. 2// License & terms of use: http://www.unicode.org/copyright.html#License 3/* 4 ******************************************************************************* 5 * Copyright (C) 2002-2014, International Business Machines Corporation and 6 * others. All Rights Reserved. 7 ******************************************************************************* 8 */ 9 10/** 11 * Port From: ICU4C v2.1 : collate/CollationMonkeyTest 12 * Source File: $ICU4CRoot/source/test/intltest/mnkytst.cpp 13 **/ 14 15package com.ibm.icu.dev.test.collator; 16 17import java.util.Locale; 18import java.util.Random; 19 20import org.junit.Test; 21 22import com.ibm.icu.dev.test.TestFmwk; 23import com.ibm.icu.text.CollationKey; 24import com.ibm.icu.text.Collator; 25import com.ibm.icu.text.RuleBasedCollator; 26 27/** 28 * CollationMonkeyTest is a third level test class. This tests the random 29 * substrings of the default test strings to verify if the compare and 30 * sort key algorithm works correctly. For example, any string is always 31 * less than the string itself appended with any character. 32 */ 33 34public class CollationMonkeyTest extends TestFmwk { 35 36 private String source = "-abcdefghijklmnopqrstuvwxyz#&^$@"; 37 38 @Test 39 public void TestCollationKey() { 40 if(source.length() == 0) { 41 errln("CollationMonkeyTest.TestCollationKey(): source is empty - ICU_DATA not set or data missing?"); 42 return; 43 } 44 Collator myCollator; 45 try { 46 myCollator = Collator.getInstance(new Locale("en", "US")); 47 } catch (Exception e) { 48 warnln("ERROR: in creation of collator of ENGLISH locale"); 49 return; 50 } 51 52 Random rand = createRandom(); // use test framework's random seed 53 int s = rand.nextInt(0x7fff) % source.length(); 54 int t = rand.nextInt(0x7fff) % source.length(); 55 int slen = Math.abs(rand.nextInt(0x7fff) % source.length() - source.length()) % source.length(); 56 int tlen = Math.abs(rand.nextInt(0x7fff) % source.length() - source.length()) % source.length(); 57 String subs = source.substring(Math.min(s, slen), Math.min(s + slen, source.length())); 58 String subt = source.substring(Math.min(t, tlen), Math.min(t + tlen, source.length())); 59 60 CollationKey collationKey1, collationKey2; 61 62 myCollator.setStrength(Collator.TERTIARY); 63 collationKey1 = myCollator.getCollationKey(subs); 64 collationKey2 = myCollator.getCollationKey(subt); 65 int result = collationKey1.compareTo(collationKey2); // Tertiary 66 int revResult = collationKey2.compareTo(collationKey1); // Tertiary 67 report( subs, subt, result, revResult); 68 69 myCollator.setStrength(Collator.SECONDARY); 70 collationKey1 = myCollator.getCollationKey(subs); 71 collationKey2 = myCollator.getCollationKey(subt); 72 result = collationKey1.compareTo(collationKey2); // Secondary 73 revResult = collationKey2.compareTo(collationKey1); // Secondary 74 report( subs, subt, result, revResult); 75 76 myCollator.setStrength(Collator.PRIMARY); 77 collationKey1 = myCollator.getCollationKey(subs); 78 collationKey2 = myCollator.getCollationKey(subt); 79 result = collationKey1.compareTo(collationKey2); // Primary 80 revResult = collationKey2.compareTo(collationKey1); // Primary 81 report(subs, subt, result, revResult); 82 83 String msg = ""; 84 String addOne = subs + String.valueOf(0xE000); 85 86 collationKey1 = myCollator.getCollationKey(subs); 87 collationKey2 = myCollator.getCollationKey(addOne); 88 result = collationKey1.compareTo(collationKey2); 89 if (result != -1) { 90 msg += "CollationKey("; 91 msg += subs; 92 msg += ") .LT. CollationKey("; 93 msg += addOne; 94 msg += ") Failed."; 95 errln(msg); 96 } 97 98 msg = ""; 99 result = collationKey2.compareTo(collationKey1); 100 if (result != 1) { 101 msg += "CollationKey("; 102 msg += addOne; 103 msg += ") .GT. CollationKey("; 104 msg += subs; 105 msg += ") Failed."; 106 errln(msg); 107 } 108 } 109 110 // perform monkey tests using Collator.compare 111 @Test 112 public void TestCompare() { 113 if(source.length() == 0) { 114 errln("CollationMonkeyTest.TestCompare(): source is empty - ICU_DATA not set or data missing?"); 115 return; 116 } 117 118 Collator myCollator; 119 try { 120 myCollator = Collator.getInstance(new Locale("en", "US")); 121 } catch (Exception e) { 122 warnln("ERROR: in creation of collator of ENGLISH locale"); 123 return; 124 } 125 126 /* Seed the random-number generator with current time so that 127 * the numbers will be different every time we run. 128 */ 129 130 Random rand = createRandom(); // use test framework's random seed 131 int s = rand.nextInt(0x7fff) % source.length(); 132 int t = rand.nextInt(0x7fff) % source.length(); 133 int slen = Math.abs(rand.nextInt(0x7fff) % source.length() - source.length()) % source.length(); 134 int tlen = Math.abs(rand.nextInt(0x7fff) % source.length() - source.length()) % source.length(); 135 String subs = source.substring(Math.min(s, slen), Math.min(s + slen, source.length())); 136 String subt = source.substring(Math.min(t, tlen), Math.min(t + tlen, source.length())); 137 138 myCollator.setStrength(Collator.TERTIARY); 139 int result = myCollator.compare(subs, subt); // Tertiary 140 int revResult = myCollator.compare(subt, subs); // Tertiary 141 report(subs, subt, result, revResult); 142 143 myCollator.setStrength(Collator.SECONDARY); 144 result = myCollator.compare(subs, subt); // Secondary 145 revResult = myCollator.compare(subt, subs); // Secondary 146 report(subs, subt, result, revResult); 147 148 myCollator.setStrength(Collator.PRIMARY); 149 result = myCollator.compare(subs, subt); // Primary 150 revResult = myCollator.compare(subt, subs); // Primary 151 report(subs, subt, result, revResult); 152 153 String msg = ""; 154 String addOne = subs + String.valueOf(0xE000); 155 156 result = myCollator.compare(subs, addOne); 157 if (result != -1) { 158 msg += "Test : "; 159 msg += subs; 160 msg += " .LT. "; 161 msg += addOne; 162 msg += " Failed."; 163 errln(msg); 164 } 165 166 msg = ""; 167 result = myCollator.compare(addOne, subs); 168 if (result != 1) { 169 msg += "Test : "; 170 msg += addOne; 171 msg += " .GT. "; 172 msg += subs; 173 msg += " Failed."; 174 errln(msg); 175 } 176 } 177 178 void report(String s, String t, int result, int revResult) { 179 if (revResult != -result) { 180 String msg = ""; 181 msg += s; 182 msg += " and "; 183 msg += t; 184 msg += " round trip comparison failed"; 185 msg += " (result " + result + ", reverse Result " + revResult + ")"; 186 errln(msg); 187 } 188 } 189 190 @Test 191 public void TestRules() { 192 String testSourceCases[] = { 193 "\u0061\u0062\u007a", 194 "\u0061\u0062\u007a", 195 }; 196 197 String testTargetCases[] = { 198 "\u0061\u0062\u00e4", 199 "\u0061\u0062\u0061\u0308", 200 }; 201 202 int i=0; 203 logln("Demo Test 1 : Create a new table collation with rules \"& z < 0x00e4\""); 204 Collator col = Collator.getInstance(new Locale("en", "US")); 205 String baseRules = ((RuleBasedCollator)col).getRules(); 206 String newRules = " & z < "; 207 newRules = baseRules + newRules + String.valueOf(0x00e4); 208 RuleBasedCollator myCollation = null; 209 try { 210 myCollation = new RuleBasedCollator(newRules); 211 } catch (Exception e) { 212 warnln( "Demo Test 1 Table Collation object creation failed."); 213 return; 214 } 215 216 for(i=0; i<2; i++){ 217 doTest(myCollation, testSourceCases[i], testTargetCases[i], -1); 218 } 219 logln("Demo Test 2 : Create a new table collation with rules \"& z < a 0x0308\""); 220 newRules = ""; 221 newRules = baseRules + " & z < a" + String.valueOf(0x0308); 222 try { 223 myCollation = new RuleBasedCollator(newRules); 224 } catch (Exception e) { 225 errln( "Demo Test 1 Table Collation object creation failed."); 226 return; 227 } 228 for(i=0; i<2; i++){ 229 doTest(myCollation, testSourceCases[i], testTargetCases[i], -1); 230 } 231 } 232 233 void doTest(RuleBasedCollator myCollation, String mysource, String target, int result) { 234 int compareResult = myCollation.compare(source, target); 235 CollationKey sortKey1, sortKey2; 236 237 try { 238 sortKey1 = myCollation.getCollationKey(source); 239 sortKey2 = myCollation.getCollationKey(target); 240 } catch (Exception e) { 241 errln("SortKey generation Failed.\n"); 242 return; 243 } 244 int keyResult = sortKey1.compareTo(sortKey2); 245 reportCResult( mysource, target, sortKey1, sortKey2, compareResult, keyResult, compareResult, result ); 246 } 247 248 public void reportCResult(String src, String target, CollationKey sourceKey, CollationKey targetKey, 249 int compareResult, int keyResult, int incResult, int expectedResult ) { 250 if (expectedResult < -1 || expectedResult > 1) { 251 errln("***** invalid call to reportCResult ****"); 252 return; 253 } 254 boolean ok1 = (compareResult == expectedResult); 255 boolean ok2 = (keyResult == expectedResult); 256 boolean ok3 = (incResult == expectedResult); 257 if (ok1 && ok2 && ok3 && !isVerbose()) { 258 return; 259 } else { 260 String msg1 = ok1? "Ok: compare(\"" : "FAIL: compare(\""; 261 String msg2 = "\", \""; 262 String msg3 = "\") returned "; 263 String msg4 = "; expected "; 264 String sExpect = new String(""); 265 String sResult = new String(""); 266 sResult = CollationTest.appendCompareResult(compareResult, sResult); 267 sExpect = CollationTest.appendCompareResult(expectedResult, sExpect); 268 if (ok1) { 269 logln(msg1 + src + msg2 + target + msg3 + sResult); 270 } else { 271 errln(msg1 + src + msg2 + target + msg3 + sResult + msg4 + sExpect); 272 } 273 msg1 = ok2 ? "Ok: key(\"" : "FAIL: key(\""; 274 msg2 = "\").compareTo(key(\""; 275 msg3 = "\")) returned "; 276 sResult = CollationTest.appendCompareResult(keyResult, sResult); 277 if (ok2) { 278 logln(msg1 + src + msg2 + target + msg3 + sResult); 279 } else { 280 errln(msg1 + src + msg2 + target + msg3 + sResult + msg4 + sExpect); 281 msg1 = " "; 282 msg2 = " vs. "; 283 errln(msg1 + CollationTest.prettify(sourceKey) + msg2 + CollationTest.prettify(targetKey)); 284 } 285 msg1 = ok3 ? "Ok: incCompare(\"" : "FAIL: incCompare(\""; 286 msg2 = "\", \""; 287 msg3 = "\") returned "; 288 sResult = CollationTest.appendCompareResult(incResult, sResult); 289 if (ok3) { 290 logln(msg1 + src + msg2 + target + msg3 + sResult); 291 } else { 292 errln(msg1 + src + msg2 + target + msg3 + sResult + msg4 + sExpect); 293 } 294 } 295 } 296} 297