1 package org.unicode.cldr.util; 2 3 import java.util.Arrays; 4 import java.util.HashSet; 5 import java.util.Iterator; 6 import java.util.LinkedHashSet; 7 import java.util.Map; 8 import java.util.Map.Entry; 9 import java.util.Set; 10 11 import org.unicode.cldr.util.StandardCodes.LstrType; 12 import org.unicode.cldr.util.StringRange.Adder; 13 import org.unicode.cldr.util.Validity.Status; 14 15 import com.google.common.base.Joiner; 16 import com.google.common.base.Splitter; 17 import com.ibm.icu.dev.test.TestFmwk; 18 import com.ibm.icu.text.NumberFormat; 19 20 public class StringRangeTest extends TestFmwk { main(String[] args)21 public static void main(String[] args) { 22 new StringRangeTest().run(args); 23 } 24 show(Set<String> output)25 static String show(Set<String> output) { 26 StringBuilder b = new StringBuilder(); 27 for (String s : output) { 28 append(b, s); 29 } 30 return b.toString(); 31 } 32 append(StringBuilder b, String start)33 static void append(StringBuilder b, String start) { 34 if (start.codePointCount(0, start.length()) == 1) { 35 b.append(start); 36 } else { 37 b.append('{').append(start).append('}'); 38 } 39 } 40 TestSimple()41 public void TestSimple() { 42 String[][] tests = { 43 { "a", "cd", 44 "Must have start-length ≥ end-length", 45 "", "" 46 }, 47 { "a", "", 48 "Must have end-length > 0", 49 "", "" 50 }, 51 { "ab", "ad", 52 "{ab}{ac}{ad}", 53 "{ab}-{ad}", 54 "{ab}-d", 55 "{ab}-{ad}", 56 "{ab}-d" 57 }, 58 { "ab", "cd", 59 "{ab}{ac}{ad}{bb}{bc}{bd}{cb}{cc}{cd}", 60 "{ab}-{ad} {bb}-{bd} {cb}-{cd}", 61 "{ab}-d {bb}-d {cb}-d", 62 "{ab}-{cd}", 63 "{ab}-{cd}" 64 }, 65 { "", "", 66 "{}{}{}{}{}", 67 "{}-{}", 68 "{}-", 69 "{}-{}", 70 "{}-" 71 }, 72 { "qax", "cx", 73 "{qax}{qax}{qax}{qax}{qax}{qbx}{qbx}{qbx}{qbx}{qbx}{qcx}{qcx}{qcx}{qcx}{qcx}", 74 "{qax}-{qax} {qbx}-{qbx} {qcx}-{qcx}", 75 "{qax}- {qbx}- {qcx}-", 76 "{qax}-{qcx}", 77 "{qax}-{cx}" 78 }, 79 }; 80 final StringBuilder b = new StringBuilder(); 81 Adder myAdder = new Adder() { // for testing: doesn't do quoting, etc 82 @Override 83 public void add(String start, String end) { 84 if (b.length() != 0) { 85 b.append(' '); 86 } 87 append(b, start); 88 if (end != null) { 89 b.append('-'); 90 append(b, end); 91 } 92 } 93 }; 94 95 for (String[] test : tests) { 96 Set<String> output = new LinkedHashSet<>(); 97 final String start = test[0]; 98 final String end = test[1]; 99 String expectedExpand = test[2]; 100 try { 101 StringRange.expand(start, end, output); 102 assertEquals("Expand " + start + "-" + end, expectedExpand, show(output)); 103 } catch (Exception e) { 104 assertEquals("Expand " + start + "-" + end, expectedExpand, e.getMessage()); 105 continue; 106 } 107 int expectedIndex = 3; 108 for (Boolean more : Arrays.asList(false, true)) { 109 for (Boolean shorterPairs : Arrays.asList(false, true)) { 110 b.setLength(0); 111 String expectedCompact = test[expectedIndex++]; 112 final String message = "Compact " + output.toString() + ", " + shorterPairs + ", " + more + "\n\t"; 113 try { 114 StringRange.compact(output, myAdder, shorterPairs, more); 115 assertEquals(message, expectedCompact, b.toString()); 116 } catch (Exception e) { 117 assertEquals(message, null, e.getMessage()); 118 } 119 } 120 } 121 } 122 } 123 124 static final Splitter ONSPACE = Splitter.on(' ').omitEmptyStrings(); 125 static final Splitter ONTILDE = Splitter.on('~').omitEmptyStrings(); 126 TestWithValidity()127 public void TestWithValidity() { 128 final StringBuilder b = new StringBuilder(); 129 Adder myAdder = new Adder() { // for testing: doesn't do quoting, etc 130 @Override 131 public void add(String start, String end) { 132 if (b.length() != 0) { 133 b.append(' '); 134 } 135 b.append(start); 136 if (end != null) { 137 b.append('~'); 138 b.append(end); 139 } 140 } 141 }; 142 143 Validity validity = Validity.getInstance(); 144 NumberFormat pf = NumberFormat.getPercentInstance(); 145 146 for (LstrType type : LstrType.values()) { 147 final Map<Status, Set<String>> statusToCodes = validity.getStatusToCodes(type); 148 for (Entry<Status, Set<String>> entry2 : statusToCodes.entrySet()) { 149 Set<String> values = entry2.getValue(); 150 String raw = Joiner.on(" ").join(values); 151 double rawsize = raw.length(); 152 for (Boolean more : Arrays.asList(false, true)) { 153 for (Boolean shorterPairs : Arrays.asList(false, true)) { 154 Status key = entry2.getKey(); 155 // if (key != Status.deprecated) continue; 156 b.setLength(0); 157 if (more) { 158 StringRange.compact(values, myAdder, shorterPairs, true); 159 } else { 160 StringRange.compact(values, myAdder, shorterPairs); 161 } 162 String compacted2 = b.toString(); 163 logln(type + ":" + key + ":\t" + compacted2.length() + "/" + raw.length() + " = " 164 + pf.format(compacted2.length() / rawsize - 1.00000000000001) + "\t" + compacted2); 165 Set<String> restored = new HashSet<>(); 166 for (String part : ONSPACE.split(compacted2)) { 167 Iterator<String> mini = ONTILDE.split(part).iterator(); 168 String main = mini.next(); 169 if (mini.hasNext()) { 170 StringRange.expand(main, mini.next(), restored); 171 } else { 172 restored.add(main); 173 } 174 } 175 assertEquals(type + ":" + key + "," + more + "," + shorterPairs, values, restored); 176 } 177 } 178 } 179 } 180 } 181 } 182