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