1 /* 2 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 4406815 8222969 27 * @summary RuleBasedCollatorTest uses very limited but selected test data 28 * to test basic functionalities provided by RuleBasedCollator. 29 * @run testng/othervm RuleBasedCollatorTest 30 */ 31 32 import java.text.CollationElementIterator; 33 import java.text.CollationKey; 34 import java.text.RuleBasedCollator; 35 import java.text.Collator; 36 import java.text.ParseException; 37 import java.util.Arrays; 38 import java.util.Locale; 39 40 import org.testng.annotations.BeforeGroups; 41 import org.testng.annotations.DataProvider; 42 import org.testng.annotations.Test; 43 import org.testng.SkipException; 44 import static org.testng.Assert.*; 45 46 public class RuleBasedCollatorTest { 47 48 static RuleBasedCollator USC; 49 static String US_RULES; 50 51 @BeforeGroups("USC") setup()52 public void setup() { 53 Collator c = Collator.getInstance(Locale.US); 54 if (!(c instanceof RuleBasedCollator)) { 55 throw new SkipException("skip tests."); 56 } 57 USC = (RuleBasedCollator) c; 58 US_RULES = USC.getRules(); 59 } 60 61 62 @DataProvider(name = "rulesData") rulesData()63 Object[][] rulesData() { 64 //Basic Tailor 65 String BASIC_TAILOR_RULES = "< b=c<\u00e6;A,a"; 66 String[] BASIC_TAILOR_DATA = {"\u00e6", "b", "a", "c", "A"}; 67 String[] BASIC_TAILOR_EXPECTED = {"b", "c", "\u00e6", "A", "a"}; 68 69 //Contraction 70 String CONTRACTION_RULES = US_RULES + "& b < ch ,cH, Ch, CH < c "; 71 String[] CONTRACTION_DATA = {"b", "c", "ch", "CH", "Ch", "cH"}; 72 String[] CONTRACTION_EXPECTED = {"b", "ch", "cH", "Ch", "CH", "c"}; 73 74 //Expansion 75 String EXPANSION_RULES = US_RULES + "& ae = \u00e4 < b"; 76 String[] EXPANSION_DATA = {"ad", "af", "\u00e4"}; 77 String[] EXPANSION_EXPECTED = {"ad", "\u00e4", "af"}; 78 79 //Punctuation 80 String PUNCTUATION_RULES = US_RULES + "< ' ' < '-'"; 81 String[] PUNCTUATION_DATA = {"b-w", "b-W", "B-w", "B-W", "bW", "bw", 82 "Bw", "BW", "b w", "b W", "B w", "B W"}; 83 String[] PUNCTUATION_EXPECTED = {"bw", "bW", "Bw", "BW", "b w", "b W", 84 "B w", "B W", "b-w", "b-W", "B-w", "B-W"}; 85 86 return new Object[][] { 87 {BASIC_TAILOR_RULES, BASIC_TAILOR_DATA, BASIC_TAILOR_EXPECTED}, 88 {CONTRACTION_RULES, CONTRACTION_DATA, CONTRACTION_EXPECTED}, 89 {EXPANSION_RULES, EXPANSION_DATA, EXPANSION_EXPECTED}, 90 {PUNCTUATION_RULES, PUNCTUATION_DATA, PUNCTUATION_EXPECTED} 91 }; 92 } 93 94 @Test(dataProvider = "rulesData", groups = "USC") testRules(String rules, String[] testData, String[] expected)95 public void testRules(String rules, String[] testData, String[] expected) 96 throws ParseException { 97 Arrays.sort(testData, new RuleBasedCollator(rules)); 98 assertEquals(testData, expected); 99 100 } 101 102 @DataProvider(name = "FrenchSecondarySort") FrenchSecondarySort()103 Object[][] FrenchSecondarySort() { 104 return new Object[][] { 105 { "\u0061\u00e1\u0061", "\u00e1\u0061\u0061", 1 }, 106 //{"\u0061\u00e1", "\u00e1\u0041", 1}, //JDK-4406815 107 //{"\u00e1\u0041", "\u0061\u00e1", -1}, //JDK-4406815 108 {"\u1ea0a", "\u1ea2A", -1}, //case ignore 109 { "\u1ea0b", "\u1ea2A", 1 }, //primary overwrite 110 { "\u1e15", "\u1e1d", -1 }, //ignore sec diacritic 111 { "a", "\u1ea1", -1 } }; 112 } 113 114 @Test(dataProvider = "FrenchSecondarySort", groups = "USC") testFrenchSecondarySort(String sData, String tData, int expected)115 public void testFrenchSecondarySort(String sData, String tData, 116 int expected) throws ParseException { 117 String french_rule = "@"; 118 String rules = US_RULES + french_rule; 119 RuleBasedCollator rc = new RuleBasedCollator(rules); 120 int result = rc.compare(sData, tData); 121 assertEquals(expected, result); 122 } 123 124 @DataProvider(name = "ThaiLaoVowelConsonantSwapping") ThaiLaoVowelConsonantSwapping()125 Object[][] ThaiLaoVowelConsonantSwapping() { 126 return new Object[][] {{"\u0e44\u0e01", "\u0e40\u0e2e", -1},//swap 127 {"\u0e2e\u0e40", "\u0e01\u0e44", 1},//no swap 128 {"\u0e44\u0061", "\u0e40\u0081", 1}//no swap 129 }; 130 } 131 132 @Test(dataProvider = "ThaiLaoVowelConsonantSwapping", groups = "USC") testThaiLaoVowelConsonantSwapping(String sData, String tData, int expected)133 public void testThaiLaoVowelConsonantSwapping(String sData, String tData, 134 int expected) throws ParseException { 135 String thai_rule = "& Z < \u0e01 < \u0e2e <\u0e40 < \u0e44!"; 136 String rules = US_RULES + thai_rule; 137 RuleBasedCollator rc = new RuleBasedCollator(rules); 138 int result = rc.compare(sData, tData); 139 assertEquals(expected, result); 140 } 141 142 @Test testIgnorableCharacter()143 public void testIgnorableCharacter() throws ParseException { 144 String rule = "=f<a<c"; 145 RuleBasedCollator rc = new RuleBasedCollator(rule); 146 CollationElementIterator iter = rc.getCollationElementIterator("f"); 147 int element = iter.next(); 148 int primary = iter.primaryOrder(element); 149 assertEquals(primary, 0); 150 } 151 152 @DataProvider(name = "Normalization") Normalization()153 Object[][] Normalization() { 154 return new Object[][] { 155 //micro sign has no canonical decomp mapping 156 // 0:NO_Decomposition; 157 // 1:CANONICAL_Decomposition; 158 // 2:FULL_Decomposition 159 {"\u00b5", "\u03BC", 0, -1}, 160 {"\u00b5", "\u03BC", 1, -1}, 161 {"\u00b5", "\u03BC", 2, 0} 162 }; 163 } 164 165 @Test(dataProvider = "Normalization", groups = "USC") testNormalization(String sData, String tData, int decomp, int result)166 public void testNormalization(String sData, String tData, int decomp, 167 int result) { 168 RuleBasedCollator rc = (RuleBasedCollator)USC.clone(); 169 rc.setDecomposition(decomp); 170 assertEquals(rc.compare(sData, tData), result); 171 } 172 173 @Test testEquality()174 public void testEquality() throws ParseException { 175 String rule1 = "<a=b"; 176 RuleBasedCollator rc1= new RuleBasedCollator(rule1); 177 //test equals() 178 assertTrue(rc1.equals(new RuleBasedCollator(rule1))); 179 180 //test semantic equality 181 String[] array1 = {"b", "c", "a"}; 182 String[] array2 = Arrays.copyOf(array1, array1.length); 183 String[] expected = {"b", "a", "c"}; 184 String rule2 = "<b=a"; 185 RuleBasedCollator rc2= new RuleBasedCollator(rule2); 186 187 Arrays.sort(array1, rc1); 188 Arrays.sort(array2, rc2); 189 assertEquals(array1, array2); 190 assertEquals(array1, expected); 191 } 192 193 @Test testBasicParsingOrder()194 public void testBasicParsingOrder() throws ParseException { 195 String rule1 = "< a < b & a < c"; 196 String rule2 = "< a < c & a < b"; 197 String rule3 = "< a < b < c"; 198 String s = "abc"; 199 RuleBasedCollator c1 = new RuleBasedCollator(rule1); 200 RuleBasedCollator c2 = new RuleBasedCollator(rule2); 201 RuleBasedCollator c3 = new RuleBasedCollator(rule3); 202 CollationKey k1 = c1.getCollationKey(s); 203 CollationKey k2 = c2.getCollationKey(s); 204 CollationKey k3 = c3.getCollationKey(s); 205 //rule1 should not equals to rule2 206 assertEquals(k1.compareTo(k2) == 0, false); 207 208 //rule2 should equals to rule3 209 assertEquals(k2.compareTo(k3) == 0, true); 210 } 211 212 @DataProvider(name = "ParseData") ParseData()213 Object[][] ParseData() { 214 return new Object[][] { 215 {""}, 216 {"a < b"}, 217 {"< a-b < c"}, 218 {"< ,a"}, 219 {"< a < b & c < d"} 220 }; 221 } 222 223 @Test(dataProvider = "ParseData", 224 expectedExceptions = ParseException.class) testParseException(String rule)225 public void testParseException(String rule) throws ParseException{ 226 new RuleBasedCollator(rule); 227 } 228 229 @Test(expectedExceptions = NullPointerException.class) testNullParseException()230 public void testNullParseException() throws ParseException{ 231 new RuleBasedCollator(null); 232 } 233 } 234