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