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