xref: /aosp_15_r20/external/cldr/tools/cldr-code/src/test/java/org/unicode/cldr/unittest/TestCompactNumbers.java (revision 912701f9769bb47905792267661f0baf2b85bed5)
1 package org.unicode.cldr.unittest;
2 
3 import com.google.common.base.Objects;
4 import com.ibm.icu.impl.locale.XCldrStub.Splitter;
5 import com.ibm.icu.impl.number.DecimalQuantity;
6 import com.ibm.icu.impl.number.DecimalQuantity_DualStorageBCD;
7 import com.ibm.icu.text.CompactDecimalFormat;
8 import com.ibm.icu.text.CompactDecimalFormat.CompactStyle;
9 import com.ibm.icu.text.DecimalFormat;
10 import com.ibm.icu.text.NumberFormat;
11 import com.ibm.icu.util.Currency;
12 import com.ibm.icu.util.ULocale;
13 import java.util.LinkedHashSet;
14 import java.util.Map;
15 import java.util.Map.Entry;
16 import java.util.Set;
17 import org.unicode.cldr.test.BuildIcuCompactDecimalFormat;
18 import org.unicode.cldr.test.BuildIcuCompactDecimalFormat.CurrencyStyle;
19 import org.unicode.cldr.util.CLDRConfig;
20 import org.unicode.cldr.util.CLDRFile;
21 import org.unicode.cldr.util.Factory;
22 import org.unicode.cldr.util.ICUServiceBuilder;
23 import org.unicode.cldr.util.StandardCodes;
24 import org.unicode.cldr.util.SupplementalDataInfo;
25 import org.unicode.cldr.util.SupplementalDataInfo.PluralInfo;
26 import org.unicode.cldr.util.SupplementalDataInfo.PluralInfo.Count;
27 import org.unicode.cldr.util.VerifyCompactNumbers;
28 
29 public class TestCompactNumbers extends TestFmwkPlus {
30     static final boolean DEBUG = false;
31     private static StandardCodes sc = StandardCodes.make();
32     private static final CLDRConfig CLDRCONFIG = CLDRConfig.getInstance();
33     private static final SupplementalDataInfo SDI = CLDRCONFIG.getSupplementalDataInfo();
34     private static final CLDRFile ENGLISH = CLDRCONFIG.getEnglish();
35     private static final Factory factory2 = CLDRCONFIG.getCldrFactory();
36 
main(String[] args)37     public static void main(String[] args) {
38         new TestCompactNumbers().run(args);
39     }
40 
TestVerify()41     public void TestVerify() {
42         // Just verify no crashes
43         CLDRFile cldrFile = factory2.make("it", true);
44         Appendable out = new StringBuilder();
45         VerifyCompactNumbers.showNumbers(cldrFile, true, "EUR", out, factory2);
46         if (DEBUG) {
47             System.out.println(out);
48         }
49     }
50 
TestInternals()51     public void TestInternals() {
52         // Just verify no crashes
53         String locale = "it";
54         String currencyCode = "EUR";
55         ULocale locale2 = ULocale.forLanguageTag(locale);
56         CLDRFile cldrFile = factory2.make(locale, true);
57         Set<String> debugCreationErrors = new LinkedHashSet<>();
58         String[] debugOriginals = null;
59 
60         ICUServiceBuilder builder = new ICUServiceBuilder().setCldrFile(cldrFile);
61         NumberFormat nf = builder.getNumberFormat(1);
62 
63         CompactDecimalFormat cdf =
64                 BuildIcuCompactDecimalFormat.build(
65                         cldrFile,
66                         debugCreationErrors,
67                         debugOriginals,
68                         CompactStyle.SHORT,
69                         locale2,
70                         CurrencyStyle.PLAIN,
71                         currencyCode);
72 
73         Map<String, Map<String, String>> data =
74                 BuildIcuCompactDecimalFormat.buildCustomData(
75                         cldrFile, CompactStyle.SHORT, CurrencyStyle.PLAIN);
76         if (DEBUG) {
77             for (Entry<String, Map<String, String>> entry : data.entrySet()) {
78                 System.out.println(entry);
79             }
80         }
81 
82         CompactDecimalFormat cdfs =
83                 BuildIcuCompactDecimalFormat.build(
84                         cldrFile,
85                         debugCreationErrors,
86                         debugOriginals,
87                         CompactStyle.LONG,
88                         locale2,
89                         CurrencyStyle.PLAIN,
90                         currencyCode);
91         CompactDecimalFormat cdfCurr =
92                 BuildIcuCompactDecimalFormat.build(
93                         cldrFile,
94                         debugCreationErrors,
95                         debugOriginals,
96                         CompactStyle.SHORT,
97                         locale2,
98                         CurrencyStyle.CURRENCY,
99                         currencyCode);
100 
101         Set<Double> allSamples =
102                 VerifyCompactNumbers.collectSamplesAndSetFormats(
103                         currencyCode, locale, SDI, cdf, cdfs, cdfCurr);
104 
105         for (double source : allSamples) {
106             if (false && source == 22000000 && locale.equals("cs")) {
107                 System.out.println("**");
108             }
109 
110             String formattedNumber = nf.format(source);
111             String compactFormattedNumber = cdf == null ? "n/a" : cdf.format(source);
112             String compactLongFormattedNumber = cdfs == null ? "n/a" : cdfs.format(source);
113             String compactCurrFormattedNumber = cdfs == null ? "n/a" : cdfCurr.format(source);
114             if (DEBUG)
115                 System.out.println(
116                         source
117                                 + "\tnf:\t"
118                                 + formattedNumber
119                                 + "\tcnf:\t"
120                                 + compactFormattedNumber
121                                 + "\tclnf:\t"
122                                 + compactLongFormattedNumber
123                                 + "\tccnf:\t"
124                                 + compactCurrFormattedNumber);
125         }
126     }
127 
128     /**
129      * Test case for VerifyCompactNumbers https://unicode-org.atlassian.net/browse/CLDR-15737
130      * https://unicode-org.atlassian.net/browse/CLDR-15762
131      */
TestVerifyCompactNumbers()132     public void TestVerifyCompactNumbers() {
133         Set<String> debugCreationErrors = new LinkedHashSet<>();
134         String[] debugOriginals = null;
135         String oldLocale = "";
136         String oldCurrencyCode = "";
137         CompactDecimalFormat cdfCurr = null;
138         CompactStyle compactStyle = null;
139         CurrencyStyle currencyStyle = null;
140         CLDRFile cldrFile = null;
141 
142         Object[][] tests = {
143             {"cs", null, 1100000d, "1,1 milionu"}, // should be 'many', not 1,1 milionů == 'other'
144             /* Background for cs
145              * <pattern type="1000000" count="one">0 milion</pattern>
146              * <pattern type="1000000" count="few">0 miliony</pattern>
147              * <pattern type="1000000" count="many">0 milionu</pattern>
148              * <pattern type="1000000" count="other">0 milionů</pattern>
149              * https://unicode-org.github.io/cldr-staging/charts/41/supplemental/language_plural_rules.html#cs
150              */
151             {"fr", "EUR", 100d, "100 €"},
152             {"fr", "EUR", 1000d, "1 k €"},
153         };
154 
155         for (Object[] row : tests) {
156             String locale = row[0].toString();
157             String currencyCode = row[1] == null ? null : row[1].toString();
158             double value = (double) row[2];
159             String expected = row[3].toString();
160 
161             if (!locale.equals(oldLocale) || Objects.equal(currencyCode, oldCurrencyCode)) {
162                 oldLocale = locale;
163                 oldCurrencyCode = currencyCode;
164                 cldrFile = factory2.make(locale, true);
165 
166                 debugCreationErrors.clear();
167                 if (currencyCode == null) {
168                     compactStyle = CompactStyle.LONG;
169                     currencyStyle = CurrencyStyle.PLAIN;
170 
171                     cdfCurr =
172                             BuildIcuCompactDecimalFormat.build(
173                                     cldrFile,
174                                     debugCreationErrors,
175                                     debugOriginals,
176                                     compactStyle,
177                                     ULocale.forLanguageTag(locale),
178                                     currencyStyle,
179                                     null);
180 
181                     // note: custom data looks good:
182                     // 1000000={other=0 milionů, one=0 milion, few=0 miliony, many=0 milionu}
183 
184                 } else {
185                     compactStyle = CompactStyle.SHORT;
186                     currencyStyle = CurrencyStyle.CURRENCY;
187 
188                     cdfCurr =
189                             BuildIcuCompactDecimalFormat.build(
190                                     cldrFile,
191                                     debugCreationErrors,
192                                     debugOriginals,
193                                     compactStyle,
194                                     ULocale.forLanguageTag(locale),
195                                     currencyStyle,
196                                     currencyCode);
197 
198                     cdfCurr.setCurrency(Currency.getInstance(currencyCode));
199                     int sigDigits = 3;
200                     cdfCurr.setMaximumSignificantDigits(sigDigits);
201                 }
202             }
203             String actual = cdfCurr.format(value);
204             if (!assertEquals("Formatted " + value, expected, actual)) {
205                 if (DEBUG) {
206                     PluralInfo rules = SupplementalDataInfo.getInstance().getPlurals(locale);
207                     int v, f, e;
208                     DecimalQuantity dq = DecimalQuantity_DualStorageBCD.fromExponentString("1.1");
209                     Count count = rules.getCount(dq);
210                     System.out.println("Locale: " + locale);
211                     ICUServiceBuilder builder = new ICUServiceBuilder().setCldrFile(cldrFile);
212 
213                     DecimalFormat decimalFormat =
214                             currencyStyle == CurrencyStyle.PLAIN
215                                     ? builder.getNumberFormat(1)
216                                     : builder.getCurrencyFormat(currencyCode);
217                     final String pattern = decimalFormat.toPattern();
218 
219                     System.out.println("Fallback pattern: " + pattern);
220                     System.out.println("Plural Rules: ");
221                     semiSplit
222                             .split(rules.getRules())
223                             .forEach(x -> System.out.println("\t" + x + ";"));
224                     System.out.println("Plural sample result: " + dq + " => " + count);
225 
226                     Map<String, Map<String, String>> customData =
227                             BuildIcuCompactDecimalFormat.buildCustomData(
228                                     cldrFile, compactStyle, currencyStyle);
229                     customData.forEach((k, vv) -> System.out.println("\t" + k + "\t" + vv));
230                 }
231             }
232         }
233     }
234 
235     static final Splitter semiSplit = Splitter.on(';').trimResults();
236 }
237