xref: /aosp_15_r20/external/cldr/tools/cldr-code/src/test/java/org/unicode/cldr/util/TestCLDRFile.java (revision 912701f9769bb47905792267661f0baf2b85bed5)
1 package org.unicode.cldr.util;
2 
3 import static org.junit.jupiter.api.Assertions.assertAll;
4 import static org.junit.jupiter.api.Assertions.assertEquals;
5 import static org.junit.jupiter.api.Assertions.assertFalse;
6 import static org.junit.jupiter.api.Assertions.assertNotEquals;
7 import static org.junit.jupiter.api.Assertions.assertNotNull;
8 import static org.junit.jupiter.api.Assertions.assertNull;
9 import static org.junit.jupiter.api.Assertions.assertThrows;
10 import static org.junit.jupiter.api.Assertions.assertTrue;
11 
12 import java.io.File;
13 import java.nio.file.Path;
14 import java.util.Comparator;
15 import java.util.Iterator;
16 import java.util.List;
17 import java.util.Set;
18 import org.junit.jupiter.api.BeforeAll;
19 import org.junit.jupiter.api.Disabled;
20 import org.junit.jupiter.api.Test;
21 import org.junit.jupiter.params.ParameterizedTest;
22 import org.junit.jupiter.params.provider.EnumSource;
23 import org.junit.jupiter.params.provider.ValueSource;
24 import org.unicode.cldr.test.CheckMetazones;
25 import org.unicode.cldr.tool.PathInfo;
26 import org.unicode.cldr.util.CLDRFile.DraftStatus;
27 import org.unicode.cldr.util.LocaleInheritanceInfo.Reason;
28 import org.unicode.cldr.util.SimpleFactory.NoSourceDirectoryException;
29 
30 /**
31  * This contains additional tests in JUnit.
32  *
33  * @see {@link org.unicode.cldr.unittest.TestCLDRFile}
34  * @see {@link CLDRFile}
35  */
36 public class TestCLDRFile {
37 
38     static Factory factory = null;
39 
40     @BeforeAll
setUp()41     public static void setUp() throws Exception {
42         factory = CLDRConfig.getInstance().getFullCldrFactory();
43     }
44 
45     @ParameterizedTest
46     @ValueSource(
47             strings = {
48                 "de", "fr", "root",
49             })
TestExtraMetazonePaths(String locale)50     public void TestExtraMetazonePaths(String locale) {
51         CLDRFile f = factory.make(locale, true);
52         assertNotNull(f, "CLDRFile for " + locale);
53         Set<String> rawExtraPaths = f.getRawExtraPaths();
54         assertNotNull(rawExtraPaths, "RawExtraPaths for " + locale);
55         for (final String path : rawExtraPaths) {
56             if (path.indexOf("/metazone") >= 0) {
57                 assertFalse(
58                         CheckMetazones.isDSTPathForNonDSTMetazone(path),
59                         "DST path for non-DST zone: " + locale + ":" + path);
60             }
61         }
62     }
63 
64     @ParameterizedTest
65     @EnumSource(value = DraftStatus.class)
TestDraftStatus(DraftStatus status)66     public void TestDraftStatus(DraftStatus status) {
67         final String asXpath = status.asXpath();
68         if (status == DraftStatus.approved) {
69             assertEquals("", asXpath, "for " + status);
70         } else {
71             assertNotEquals("", asXpath, "for " + status);
72         }
73         assertAll(
74                 "misc tests for " + status,
75                 () -> assertEquals(status, DraftStatus.forXpath("//ldml/someLeaf" + asXpath)),
76                 () -> assertEquals(status, DraftStatus.forString(status.name())),
77                 () -> assertEquals(status, DraftStatus.forString(status.name().toUpperCase())));
78 
79         final String oldPath1 = "//ldml/someLeaf"; // no status
80         final String oldPath2 = "//ldml/someLeaf[@draft=\"unconfirmed\"]";
81         final String oldPath3 = "//ldml/someLeaf[@draft=\"provisional\"]";
82 
83         final String newPath1 = status.updateXPath(oldPath1);
84         final String newPath2 = status.updateXPath(oldPath2);
85         final String newPath3 = status.updateXPath(oldPath3);
86 
87         final String expected = oldPath1 + status.asXpath(); // will be == oldPath1 for approved
88 
89         // all should be the same
90         assertAll(
91                 "testing " + status + ".updateXpath()",
92                 () -> assertEquals(expected, newPath1),
93                 () -> assertEquals(expected, newPath2),
94                 () -> assertEquals(expected, newPath3));
95     }
96 
97     /**
98      * Test that we can read all XML files in common. Comment out from the ValueSource any dirs that
99      * don't have XML that is suitable for CLDRFile.
100      *
101      * @param subdir
102      */
103     @ParameterizedTest
104     @ValueSource(
105             strings = {
106                 // common stuff
107                 "common/bcp47",
108                 "common/subdivisions",
109                 "common/supplemental",
110                 "common/annotations",
111                 "common/collation",
112                 "common/rbnf",
113                 /*"common/testData",*/
114                 "common/annotationsDerived",
115                 /* common/dtd */
116                 "common/segments",
117                 "common/transforms",
118                 "common/bcp47",
119                 "common/main",
120                 "common/subdivisions",
121                 /*"common/uca",*/
122                 "common/casing",
123                 /*"common/properties",*/
124                 "common/supplemental",
125                 "common/validity",
126                 "exemplars/main",
127             })
TestReadAllDTDs(final String subdir)128     public void TestReadAllDTDs(final String subdir) {
129         Path aPath = CLDRConfig.getInstance().getCldrBaseDirectory().toPath().resolve(subdir);
130         Factory factory = Factory.make(aPath.toString(), ".*");
131         assertNotNull(factory);
132 
133         // Just test one file from each dir.
134         {
135             final String id = factory.getAvailable().iterator().next(); // Get the first id.
136             TestReadAllDTDs(subdir, factory, id);
137         }
138 
139         // Test ALL files in each dir. Adds ~35s not including seed or exemplars.
140         // for (final String id : factory.getAvailable()) {
141         //     TestReadAllDTDs(subdir, factory, id);
142         // }
143     }
144 
TestReadAllDTDs(final String subdir, Factory factory, final String id)145     private void TestReadAllDTDs(final String subdir, Factory factory, final String id) {
146         CLDRFile file = factory.make(id, false);
147 
148         assertNotNull(file, id);
149         for (final String xpath : file.fullIterable()) {
150             assertNotNull(xpath, subdir + ":" + id + " xpath");
151             /*final String value = */ file.getStringValue(xpath);
152         }
153 
154         for (Iterator<String> i = file.iterator(); i.hasNext(); ) {
155             final String xpath = i.next();
156             assertNotNull(xpath, subdir + ":" + id + " xpath");
157             /*final String value = */ file.getStringValue(xpath);
158         }
159         // This is to simulate what is in the LDML2JsonConverter
160         final Comparator<String> comparator =
161                 DtdData.getInstance(file.getDtdType()).getDtdComparator(null);
162         for (Iterator<String> it = file.iterator("", comparator); it.hasNext(); ) {
163             final String xpath = it.next();
164             assertNotNull(xpath, subdir + ":" + id + " xpath");
165         }
166     }
167 
168     final File unittest_dir = new File(CLDRPaths.UNITTEST_DATA_DIR);
169     final File testcommonmain = new File(unittest_dir, "common/main");
170     final File testfile = new File(testcommonmain, "hy.xml");
171     final File rootfile = new File(testcommonmain, "root.xml");
172     final File[] dirs = {testcommonmain};
173 
getTestDataFactory()174     Factory getTestDataFactory() {
175         // Note: Uses the special test data in
176         // tools/cldr-code/src/test/resources/org/unicode/cldr/unittest/data/common/main/hy.xml
177         Factory myFactory = SimpleFactory.make(dirs, ".*");
178         return myFactory;
179     }
180 
181     @Test
testSourceLocale()182     public void testSourceLocale() {
183         // Note: Uses the special test data in
184         // tools/cldr-code/src/test/resources/org/unicode/cldr/unittest/data/common/main/hy.xml
185         final Factory myFactory = getTestDataFactory();
186         final CLDRFile hyFile = myFactory.make("hy", true);
187 
188         {
189             final String xpath = "//ldml/localeDisplayNames/languages/language[@type=\"az\"]";
190             // no location - code-fallback
191             assertNull(hyFile.getSourceLocation(xpath), "expected null location for " + xpath);
192         }
193         {
194             // found in hy.xml
195             final String xpath = "//ldml/localeDisplayNames/languages/language[@type=\"aa\"]";
196             XMLSource.SourceLocation location = hyFile.getSourceLocation(xpath);
197             assertNotNull(location, "location for " + xpath);
198             assertEquals(testfile.toPath().toString(), location.getSystem(), "system for " + xpath);
199             assertEquals(17, location.getLine(), "line for " + xpath);
200             assertEquals(43, location.getColumn(), "col for " + xpath);
201         }
202         {
203             // found in hy.xml
204             final String xpath = "//ldml/localeDisplayNames/languages/language[@type=\"ab\"]";
205             XMLSource.SourceLocation location = hyFile.getSourceLocation(xpath);
206             assertNotNull(location, "location for " + xpath);
207             assertEquals(testfile.toPath().toString(), location.getSystem(), "system for " + xpath);
208             assertEquals(18, location.getLine(), "line for " + xpath);
209             assertEquals(64, location.getColumn(), "col for " + xpath);
210         }
211         {
212             // found in root.xml
213             final String xpath =
214                     "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dayPeriods/dayPeriodContext[@type=\"format\"]/dayPeriodWidth[@type=\"wide\"]/dayPeriod[@type=\"pm\"]";
215             XMLSource.SourceLocation location = hyFile.getSourceLocation(xpath);
216             assertNotNull(location, "location for " + xpath);
217             assertEquals(rootfile.toPath().toString(), location.getSystem(), "system for " + xpath);
218             assertEquals(25, location.getLine(), "line for " + xpath);
219             assertEquals(43, location.getColumn(), "col for " + xpath);
220         }
221     }
222 
223     /**
224      * @see PathInfo
225      */
226     @Test
testGetPaths()227     public void testGetPaths() {
228         final String GERMAN_IN_SWITZERLAND =
229                 "//ldml/localeDisplayNames/languages/language[@type=\"de_CH\"]";
230         final String GERMAN = "//ldml/localeDisplayNames/languages/language[@type=\"de\"]";
231         final Factory myFactory = getTestDataFactory();
232         {
233             String locale = "en";
234             String p = GERMAN_IN_SWITZERLAND;
235             final CLDRFile f = CLDRConfig.getInstance().getCLDRFile(locale, true);
236             List<LocaleInheritanceInfo> pwf = f.getPathsWhereFound(p);
237             assertEquals(
238                     List.of(
239                             new LocaleInheritanceInfo(locale, p, Reason.value),
240                             new LocaleInheritanceInfo(XMLSource.ROOT_ID, p, Reason.none),
241                             new LocaleInheritanceInfo(null, p, Reason.codeFallback)),
242                     pwf,
243                     "For " + locale + ":" + p);
244             assertTrue(
245                     pwf.get(pwf.size() - 1).getReason().isTerminal(),
246                     "Last Reason should be terminal");
247         }
248         {
249             String locale = "en_CA";
250             String parent = "en";
251             String p = GERMAN_IN_SWITZERLAND;
252             final CLDRFile f = CLDRConfig.getInstance().getCLDRFile(locale, true);
253             List<LocaleInheritanceInfo> pwf = f.getPathsWhereFound(p);
254             assertEquals(
255                     List.of(
256                             new LocaleInheritanceInfo(locale, p, Reason.inheritanceMarker),
257                             new LocaleInheritanceInfo(parent, p, Reason.value),
258                             new LocaleInheritanceInfo(XMLSource.ROOT_ID, p, Reason.none),
259                             new LocaleInheritanceInfo(null, p, Reason.codeFallback)),
260                     pwf,
261                     "For " + locale + ":" + p);
262             assertTrue(
263                     pwf.get(pwf.size() - 1).getReason().isTerminal(),
264                     "Last Reason should be terminal");
265         }
266         {
267             String locale = "root";
268             String p = GERMAN_IN_SWITZERLAND;
269             final CLDRFile f = CLDRConfig.getInstance().getCLDRFile(locale, true);
270             List<LocaleInheritanceInfo> pwf = f.getPathsWhereFound(p);
271             assertEquals(
272                     List.of(
273                             new LocaleInheritanceInfo(
274                                     XMLSource.CODE_FALLBACK_ID, GERMAN, Reason.constructed),
275                             new LocaleInheritanceInfo(
276                                     XMLSource.ROOT_ID,
277                                     "//ldml/localeDisplayNames/localeDisplayPattern/localePattern",
278                                     Reason.constructed),
279                             new LocaleInheritanceInfo(
280                                     XMLSource.CODE_FALLBACK_ID,
281                                     "//ldml/localeDisplayNames/territories/territory[@type=\"CH\"]",
282                                     Reason.constructed),
283                             new LocaleInheritanceInfo(XMLSource.ROOT_ID, p, Reason.none),
284                             new LocaleInheritanceInfo(null, p, Reason.codeFallback)),
285                     pwf,
286                     "For " + locale + ":" + p);
287             assertTrue(
288                     pwf.get(pwf.size() - 1).getReason().isTerminal(),
289                     "Last Reason should be terminal");
290         }
291         {
292             // Note: Uses the special test data in
293             // tools/cldr-code/src/test/resources/org/unicode/cldr/unittest/data/common/main/hy.xml
294             // so we are not dependent on exact data that could change
295             String locale = "hy";
296             final String p =
297                     "//ldml/units/unitLength[@type=\"short\"]/unit[@type=\"angle-revolution\"]/unitPattern[@count=\"one\"]";
298             final String pother =
299                     "//ldml/units/unitLength[@type=\"short\"]/unit[@type=\"angle-revolution\"]/unitPattern[@count=\"other\"]";
300             final CLDRFile f = myFactory.make(locale, true);
301             List<LocaleInheritanceInfo> pwf = f.getPathsWhereFound(p);
302             assertEquals(
303                     List.of(
304                             new LocaleInheritanceInfo(locale, p, Reason.none),
305                             new LocaleInheritanceInfo(XMLSource.ROOT_ID, p, Reason.none),
306                             new LocaleInheritanceInfo(
307                                     null, pother, Reason.changedAttribute, "count"),
308                             new LocaleInheritanceInfo(locale, pother, Reason.none),
309                             new LocaleInheritanceInfo(XMLSource.ROOT_ID, pother, Reason.value),
310                             new LocaleInheritanceInfo(null, pother, Reason.codeFallback)),
311                     pwf,
312                     "For (TESTDATA) " + locale + ":" + p);
313             assertTrue(
314                     pwf.get(pwf.size() - 1).getReason().isTerminal(),
315                     "Last Reason should be terminal");
316         }
317         {
318             String locale = "hy";
319             final String p = GERMAN_IN_SWITZERLAND;
320             final CLDRFile f = myFactory.make(locale, true);
321             List<LocaleInheritanceInfo> pwf = f.getPathsWhereFound(p);
322             assertEquals(
323                     List.of(
324                             new LocaleInheritanceInfo(
325                                     XMLSource.CODE_FALLBACK_ID, GERMAN, Reason.constructed),
326                             new LocaleInheritanceInfo(
327                                     XMLSource
328                                             .CODE_FALLBACK_ID /* test data does not have this in root */,
329                                     "//ldml/localeDisplayNames/localeDisplayPattern/localePattern",
330                                     Reason.constructed),
331                             new LocaleInheritanceInfo(
332                                     XMLSource.CODE_FALLBACK_ID,
333                                     "//ldml/localeDisplayNames/territories/territory[@type=\"CH\"]",
334                                     Reason.constructed),
335                             new LocaleInheritanceInfo(locale, p, Reason.none),
336                             new LocaleInheritanceInfo(XMLSource.ROOT_ID, p, Reason.none),
337                             new LocaleInheritanceInfo(null, p, Reason.codeFallback)),
338                     pwf,
339                     "For (TESTDATA) " + locale + ":" + p);
340             assertTrue(
341                     pwf.get(pwf.size() - 1).getReason().isTerminal(),
342                     "Last Reason should be terminal");
343 
344             // new LocaleInheritanceInfo(
345 
346         }
347         {
348             // assert that throws with a non-resolved
349             assertThrows(
350                     IllegalArgumentException.class,
351                     () ->
352                             CLDRConfig.getInstance()
353                                     .getCLDRFile("en", false)
354                                     .getPathsWhereFound(GERMAN_IN_SWITZERLAND));
355         }
356     }
357 
358     @Test
TestInternedPaths()359     public void TestInternedPaths() {
360         {
361             final CLDRFile en = CLDRConfig.getInstance().getCLDRFile("en", false);
362             for (final String s : en.fullIterable()) {
363                 final String s0 = new String(s);
364                 assertTrue(s != s0);
365                 assertTrue(s == s0.intern(), () -> "in unresolved en was not interned: " + s);
366             }
367         }
368         {
369             final CLDRFile en = CLDRConfig.getInstance().getCLDRFile("en", true);
370             for (final String s : en.fullIterable()) {
371                 final String s0 = new String(s);
372                 assertTrue(s != s0);
373                 assertTrue(s == s0.intern(), () -> "in resolved en was not interned: " + s);
374             }
375         }
376     }
377 
378     @Test
379     @Disabled
380     /** enable manually - for testing performance */
TestSimpleFactoryPerf()381     public void TestSimpleFactoryPerf() {
382         for (int i = 0; i < 10000; i++) {
383             Factory baselineFactory =
384                     CLDRConfig.getInstance().getCommonAndSeedAndMainAndAnnotationsFactory();
385             baselineFactory.make("en_BE".toString(), true);
386             assertThrows(
387                     NoSourceDirectoryException.class,
388                     () -> baselineFactory.make("de_RU".toString(), true));
389             baselineFactory.make("es_MX".toString(), true);
390         }
391     }
392 }
393