1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 // 2017 and later: Unicode, Inc. and others. 3 // License & terms of use: http://www.unicode.org/copyright.html#License 4 package android.icu.dev.test.util; 5 6 import java.io.IOException; 7 import java.util.ArrayList; 8 import java.util.List; 9 import java.util.Map; 10 import java.util.Map.Entry; 11 import java.util.Set; 12 13 import org.junit.Ignore; 14 import org.junit.Test; 15 import org.junit.runner.RunWith; 16 import org.junit.runners.JUnit4; 17 18 import android.icu.dev.test.TestFmwk; 19 import android.icu.impl.locale.XLikelySubtags.LSR; 20 import android.icu.impl.locale.XLocaleDistance; 21 import android.icu.impl.locale.XLocaleDistance.DistanceNode; 22 import android.icu.impl.locale.XLocaleDistance.DistanceOption; 23 import android.icu.impl.locale.XLocaleDistance.DistanceTable; 24 import android.icu.util.LocaleMatcher; 25 import android.icu.util.Output; 26 import android.icu.util.ULocale; 27 import android.icu.testsharding.MainTestShard; 28 29 /** 30 * Test the XLocaleDistance. 31 * 32 * @author markdavis 33 */ 34 @MainTestShard 35 @RunWith(JUnit4.class) 36 public class XLocaleDistanceTest extends TestFmwk { 37 private static final boolean REFORMAT = false; // set to true to get a reformatted data file listed 38 39 public static final int FAIL = XLocaleDistance.ABOVE_THRESHOLD; 40 41 private XLocaleDistance localeMatcher = XLocaleDistance.getDefault(); 42 DataDrivenTestHelper tfh = new MyTestFileHandler() 43 .setFramework(this) 44 .load(XLocaleDistanceTest.class, "data/localeDistanceTest.txt"); 45 46 static class Arguments { 47 final ULocale desired; 48 final ULocale supported; 49 final int desiredToSupported; 50 final int supportedToDesired; 51 52 public Arguments(List<String> args) { 53 this.desired = new ULocale.Builder().setLanguageTag(args.get(0)).build(); // use more complicated expression to check syntax 54 this.supported = new ULocale.Builder().setLanguageTag(args.get(1)).build(); 55 this.desiredToSupported = Integer.parseInt(args.get(2)); 56 this.supportedToDesired = args.size() > 3 ? Integer.parseInt(args.get(3)) : this.desiredToSupported; 57 } 58 } 59 60 @Ignore("Disabled because of Linux; need to investigate.") 61 @Test 62 public void testTiming() { 63 List<Arguments> testArgs = new ArrayList<Arguments>(); 64 for (List<String> line : tfh.getLines()) { 65 if (tfh.isTestLine(line)) { 66 testArgs.add(new Arguments(line)); 67 } 68 } 69 Arguments[] tests = testArgs.toArray(new Arguments[testArgs.size()]); 70 71 final LocaleMatcher oldLocaleMatcher = new LocaleMatcher(""); 72 73 long likelyTime = 0; 74 long newLikelyTime = 0; 75 long newTimeMinusLikely = 0; 76 //long intTime = 0; 77 long oldTimeMinusLikely = 0; 78 final int maxIterations = 1000; 79 80 for (int iterations = maxIterations; iterations > 0; --iterations) { 81 // int count=0; 82 for (Arguments test : tests) { 83 final ULocale desired = test.desired; 84 final ULocale supported = test.supported; 85 //final int desiredToSupported = test.desiredToSupported; 86 //final int supportedToDesired = test.supportedToDesired; 87 88 long temp = System.nanoTime(); 89 final ULocale desiredMax = ULocale.addLikelySubtags(desired); 90 final ULocale supportedMax = ULocale.addLikelySubtags(supported); 91 likelyTime += System.nanoTime()-temp; 92 93 temp = System.nanoTime(); 94 //double distOld1 = oldLocaleMatcher.match(desired, desiredMax, supported, supportedMax); 95 //double distOld2 = oldLocaleMatcher.match(supported, supportedMax, desired, desiredMax); 96 oldTimeMinusLikely += System.nanoTime()-temp; 97 98 temp = System.nanoTime(); 99 final LSR desiredLSR = LSR.fromMaximalized(desired); 100 final LSR supportedLSR = LSR.fromMaximalized(supported); 101 newLikelyTime += System.nanoTime()-temp; 102 103 temp = System.nanoTime(); 104 int dist1 = localeMatcher.distanceRaw(desiredLSR, supportedLSR, 1000, DistanceOption.NORMAL); 105 int dist2 = localeMatcher.distanceRaw(supportedLSR, desiredLSR, 1000, DistanceOption.NORMAL); 106 newTimeMinusLikely += System.nanoTime()-temp; 107 } 108 } 109 final long oldTime = oldTimeMinusLikely+likelyTime; 110 final long newTime = newLikelyTime+newTimeMinusLikely; 111 logln("\n"); 112 logln("\tlikelyTime:\t" + likelyTime/maxIterations); 113 logln("\toldTime-likelyTime:\t" + oldTimeMinusLikely/maxIterations); 114 logln("totalOld:\t" + oldTime/maxIterations); 115 logln("\tnewLikelyTime:\t" + newLikelyTime/maxIterations); 116 logln("totalNew:\t" + newTime/maxIterations); 117 assertTrue("newTime < 20% of oldTime", newTime * 5 < oldTime); 118 //logln("\tnewIntTime-newLikelyTime-extractTime:\t" + intTime/maxIterations); 119 //logln("totalInt:\t" + (intTime)/maxIterations); 120 } 121 122 @Test 123 @SuppressWarnings("deprecation") 124 public void testInternalTable() { 125 checkTables(localeMatcher.internalGetDistanceTable(), "", 1); 126 } 127 128 @SuppressWarnings("deprecation") 129 private void checkTables(DistanceTable internalGetDistanceTable, String title, int depth) { 130 // Check that ANY, ANY is always present, and that the table has a depth of exactly 3 everyplace. 131 Map<String, Set<String>> matches = internalGetDistanceTable.getInternalMatches(); 132 133 // must have ANY,ANY 134 boolean haveANYANY = false; 135 for (Entry<String, Set<String>> entry : matches.entrySet()) { 136 String first = entry.getKey(); 137 boolean haveANYfirst = first.equals(XLocaleDistance.ANY); 138 for (String second : entry.getValue()) { 139 haveANYANY |= haveANYfirst && second.equals(XLocaleDistance.ANY); 140 DistanceNode distanceNode = internalGetDistanceTable.getInternalNode(first, second); 141 DistanceTable subDistanceTable = distanceNode.getDistanceTable(); 142 if (subDistanceTable == null || subDistanceTable.isEmpty()) { 143 if (depth != 3) { 144 logln("depth should be 3"); 145 } 146 if (distanceNode.getClass() != DistanceNode.class) { 147 logln("should be plain DistanceNode"); 148 } 149 } else { 150 if (depth >= 3) { 151 logln("depth should be 3"); 152 } 153 if (distanceNode.getClass() == DistanceNode.class) { 154 logln("should NOT be plain DistanceNode"); 155 } 156 checkTables(subDistanceTable, first + "," + second + ",", depth+1); 157 } 158 } 159 } 160 if (!haveANYANY) { 161 logln("ANY-ANY not in" + matches); 162 } 163 } 164 165 @Test 166 public void testShowDistanceTable() { 167 if (isVerbose()) { 168 System.out.println(XLocaleDistance.getDefault().toString(false)); 169 } 170 } 171 172 @Test 173 public void testDataDriven() throws IOException { 174 tfh.test(); 175 if (REFORMAT) { 176 System.out.println(tfh.appendLines(new StringBuffer())); 177 } 178 } 179 180 class MyTestFileHandler extends DataDrivenTestHelper { 181 final XLocaleDistance distance = XLocaleDistance.getDefault(); 182 Output<ULocale> bestDesired = new Output<ULocale>(); 183 private DistanceOption distanceOption = DistanceOption.NORMAL; 184 private Integer threshold = distance.getDefaultScriptDistance(); 185 186 @Override 187 public void handle(int lineNumber, boolean breakpoint, String commentBase, List<String> arguments) { 188 if (breakpoint) { 189 breakpoint = false; // put debugger breakpoint here to break at @debug in test file 190 } 191 Arguments args = new Arguments(arguments); 192 int supportedToDesiredActual = distance.distance(args.supported, args.desired, threshold, distanceOption); 193 int desiredToSupportedActual = distance.distance(args.desired, args.supported, threshold, distanceOption); 194 String desiredTag = args.desired.toLanguageTag(); 195 String supportedTag = args.supported.toLanguageTag(); 196 final String comment = commentBase.isEmpty() ? "" : "\t# " + commentBase; 197 if (assertEquals("(" + lineNumber + ") " + desiredTag + " to " + supportedTag + comment, args.desiredToSupported, desiredToSupportedActual)) { 198 assertEquals("(" + lineNumber + ") " + supportedTag + " to " + desiredTag + comment, args.supportedToDesired, supportedToDesiredActual); 199 } 200 } 201 @Override 202 public void handleParams(String comment, List<String> arguments) { 203 String switchArg = arguments.get(0); 204 if (switchArg.equals("@DistanceOption")) { 205 distanceOption = DistanceOption.valueOf(arguments.get(1)); 206 } else if (switchArg.equals("@Threshold")) { 207 threshold = Integer.valueOf(arguments.get(1)); 208 } else { 209 super.handleParams(comment, arguments); 210 } 211 return; 212 } 213 } 214 } 215