1 package org.unicode.cldr.unittest; 2 3 import java.io.File; 4 import java.util.ArrayList; 5 import java.util.Arrays; 6 import java.util.Collection; 7 import java.util.EnumMap; 8 import java.util.EnumSet; 9 import java.util.HashMap; 10 import java.util.HashSet; 11 import java.util.LinkedHashMap; 12 import java.util.LinkedHashSet; 13 import java.util.List; 14 import java.util.Map; 15 import java.util.Map.Entry; 16 import java.util.Set; 17 import java.util.TreeMap; 18 import java.util.TreeSet; 19 import java.util.regex.Matcher; 20 21 import org.unicode.cldr.test.CoverageLevel2; 22 import org.unicode.cldr.test.ExampleGenerator; 23 import org.unicode.cldr.util.CLDRConfig; 24 import org.unicode.cldr.util.CLDRFile; 25 import org.unicode.cldr.util.CLDRFile.Status; 26 import org.unicode.cldr.util.CLDRPaths; 27 import org.unicode.cldr.util.CldrUtility; 28 import org.unicode.cldr.util.Containment; 29 import org.unicode.cldr.util.Counter; 30 import org.unicode.cldr.util.DtdData; 31 import org.unicode.cldr.util.DtdType; 32 import org.unicode.cldr.util.Factory; 33 import org.unicode.cldr.util.LanguageTagParser; 34 import org.unicode.cldr.util.Level; 35 import org.unicode.cldr.util.Organization; 36 import org.unicode.cldr.util.Pair; 37 import org.unicode.cldr.util.PathDescription; 38 import org.unicode.cldr.util.PathHeader; 39 import org.unicode.cldr.util.PathHeader.PageId; 40 import org.unicode.cldr.util.PathHeader.SectionId; 41 import org.unicode.cldr.util.PathHeader.SurveyToolStatus; 42 import org.unicode.cldr.util.PathStarrer; 43 import org.unicode.cldr.util.PatternCache; 44 import org.unicode.cldr.util.PatternPlaceholders; 45 import org.unicode.cldr.util.PatternPlaceholders.PlaceholderInfo; 46 import org.unicode.cldr.util.PatternPlaceholders.PlaceholderStatus; 47 import org.unicode.cldr.util.PrettyPath; 48 import org.unicode.cldr.util.StandardCodes; 49 import org.unicode.cldr.util.SupplementalDataInfo; 50 import org.unicode.cldr.util.SupplementalDataInfo.PluralInfo; 51 import org.unicode.cldr.util.SupplementalDataInfo.PluralType; 52 import org.unicode.cldr.util.With; 53 import org.unicode.cldr.util.XMLFileReader; 54 import org.unicode.cldr.util.XPathParts; 55 56 import com.google.common.collect.HashMultimap; 57 import com.google.common.collect.ImmutableSet; 58 import com.google.common.collect.LinkedListMultimap; 59 import com.google.common.collect.Multimap; 60 import com.google.common.collect.TreeMultimap; 61 import com.ibm.icu.dev.util.CollectionUtilities; 62 import com.ibm.icu.impl.Relation; 63 import com.ibm.icu.impl.Row; 64 import com.ibm.icu.impl.Row.R2; 65 66 public class TestPathHeader extends TestFmwkPlus { 67 private static final DtdType DEBUG_DTD_TYPE = null; // DtdType.supplementalData; 68 private static final String COMMON_DIR = CLDRPaths.BASE_DIRECTORY + "common/"; 69 private static final boolean DEBUG = false; 70 main(String[] args)71 public static void main(String[] args) { 72 new TestPathHeader().run(args); 73 } 74 75 static final CLDRConfig info = CLDRConfig.getInstance(); 76 static final Factory factory = info.getCommonAndSeedAndMainAndAnnotationsFactory(); 77 static final CLDRFile english = factory.make("en", true); 78 static final SupplementalDataInfo supplemental = info 79 .getSupplementalDataInfo(); 80 static PathHeader.Factory pathHeaderFactory = PathHeader 81 .getFactory(english); 82 private EnumSet<PageId> badZonePages = EnumSet.of(PageId.UnknownT); 83 tempTestAnnotation()84 public void tempTestAnnotation() { 85 // NEW: <annotation cp="">face | grin</annotation> 86 // <annotation cp="" type="tts">grinning face</annotation> 87 88 final String path1 = "//ldml/annotations/annotation[@cp=\"\"]"; 89 PathHeader ph1 = pathHeaderFactory.fromPath(path1); 90 logln(ph1.toString() + "\t" + path1); 91 final String path2 = "//ldml/annotations/annotation[@cp=\"\"][@type=\"tts\"]"; 92 PathHeader ph2 = pathHeaderFactory.fromPath(path2); 93 logln(ph2.toString() + "\t" + path2); 94 final String path3 = "//ldml/annotations/annotation[@cp=\"\"]"; 95 PathHeader ph3 = pathHeaderFactory.fromPath(path2); 96 logln(ph3.toString() + "\t" + path3); 97 98 assertNotEquals("pathheader", ph1, ph2); 99 assertNotEquals("pathheader", ph1.toString(), ph2.toString()); 100 assertRelation("pathheader", true, ph1, TestFmwkPlus.LEQ, ph3); 101 assertRelation("pathheader", true, ph3, TestFmwkPlus.LEQ, ph2); 102 } 103 tempTestCompletenessLdmlDtd()104 public void tempTestCompletenessLdmlDtd() { 105 // List<String> failures = null; 106 pathHeaderFactory.clearCache(); 107 PathChecker pathChecker = new PathChecker(); 108 for (String directory : DtdType.ldml.directories) { 109 Factory factory2 = CLDRConfig.getInstance().getMainAndAnnotationsFactory(); 110 Set<String> source = factory2.getAvailable(); 111 for (String file : getFilesToTest(source, "root", "en", "da")) { 112 if (DEBUG) warnln(" TestCompletenessLdmlDtd: " + directory + ", " + file); 113 DtdData dtdData = null; 114 CLDRFile cldrFile = factory2.make(file, true); 115 for (String path : cldrFile.fullIterable()) { 116 pathChecker.checkPathHeader(cldrFile.getDtdData(), path); 117 } 118 } 119 } 120 Set<String> missing = pathHeaderFactory.getUnmatchedRegexes(); 121 if (missing.size() != 0) { 122 for (String e : missing) { 123 errln("Path Regex never matched:\t" + e); 124 } 125 } 126 } 127 getFilesToTest(Collection<String> source, String... doFirst)128 private Collection<String> getFilesToTest(Collection<String> source, String... doFirst) { 129 LinkedHashSet<String> files = new LinkedHashSet<>(Arrays.asList(doFirst)); 130 files.retainAll(source); // put first 131 files.addAll(new HashSet<>(source)); // now add others semi-randomly 132 int max = Math.min(30, files.size()); 133 if (getInclusion() == 10 || files.size() <= max) { 134 return files; 135 } 136 ArrayList<String> shortFiles = new ArrayList<>(files); 137 if (getInclusion() > 5) { 138 max += (files.size() - 30) * (getInclusion() - 5) / 10; // use proportional amount 139 } 140 return shortFiles.subList(0, max); 141 } 142 TestCompleteness()143 public void TestCompleteness() { 144 PathHeader.Factory pathHeaderFactory2 = PathHeader.getFactory(english); 145 // List<String> failures = null; 146 pathHeaderFactory2.clearCache(); 147 Multimap<PathHeader.PageId, PathHeader.SectionId> pageUniqueness = TreeMultimap.create(); 148 Multimap<String, Pair<PathHeader.SectionId, PathHeader.PageId>> headerUniqueness = TreeMultimap.create(); 149 Set<String> toTest; 150 switch (getInclusion()) { 151 default: 152 toTest = StandardCodes.make().getLocaleCoverageLocales(Organization.cldr); 153 break; 154 case 10: 155 toTest = factory.getAvailable(); 156 break; 157 } 158 toTest = ImmutableSet.<String> builder().add("en").addAll(toTest).build(); 159 Set<String> seenPaths = new HashSet<>(); 160 Set<String> localSeenPaths = new TreeSet<>(); 161 for (String locale : toTest) { 162 localSeenPaths.clear(); 163 for (String p : factory.make(locale, true).fullIterable()) { 164 if (p.startsWith("//ldml/identity/")) { 165 continue; 166 } 167 if (seenPaths.contains(p)) { 168 continue; 169 } 170 seenPaths.add(p); 171 localSeenPaths.add(p); 172 // if (p.contains("symbol[@alt") && failures == null) { 173 // PathHeader result = pathHeaderFactory2.fromPath(p, failures = new 174 // ArrayList<String>()); 175 // logln("Matching " + p + ": " + result + "\t" + 176 // result.getSurveyToolStatus()); 177 // for (String failure : failures) { 178 // logln("\t" + failure); 179 // } 180 // } 181 PathHeader ph = pathHeaderFactory2.fromPath(p); 182 if (ph == null) { 183 errln("Failed to create path from: " + p); 184 continue; 185 } 186 final SectionId sectionId = ph.getSectionId(); 187 if (sectionId != SectionId.Special) { 188 pageUniqueness.put(ph.getPageId(), sectionId); 189 headerUniqueness.put(ph.getHeader(), new Pair<>(sectionId, ph.getPageId())); 190 } 191 } 192 if (!localSeenPaths.isEmpty()) { 193 logln(locale + ": checked " + localSeenPaths.size() + " new paths"); 194 } 195 } 196 Set<String> missing = pathHeaderFactory2.getUnmatchedRegexes(); 197 if (missing.size() != 0) { 198 for (String e : missing) { 199 if (e.contains("//ldml/")) { 200 if (e.contains("//ldml/rbnf/") || e.contains("//ldml/segmentations/") || e.contains("//ldml/collations/")) { 201 continue; 202 } 203 logln("Path Regex never matched:\t" + e); 204 } 205 } 206 } 207 208 for (Entry<PageId, Collection<SectionId>> e : pageUniqueness.asMap().entrySet()) { 209 Collection<SectionId> values = e.getValue(); 210 if (values.size() != 1) { 211 warnln("Duplicate page in section: " + CldrUtility.toString(e)); 212 } 213 } 214 215 for (Entry<String, Collection<Pair<SectionId, PageId>>> e : headerUniqueness.asMap().entrySet()) { 216 Collection<Pair<SectionId, PageId>> values = e.getValue(); 217 if (values.size() != 1) { 218 warnln("Duplicate header in (section,page): " + CldrUtility.toString(e)); 219 } 220 } 221 } 222 Test6170()223 public void Test6170() { 224 String p1 = "//ldml/units/unitLength[@type=\"narrow\"]/unit[@type=\"speed-kilometer-per-hour\"]/unitPattern[@count=\"other\"]"; 225 String p2 = "//ldml/units/unitLength[@type=\"narrow\"]/unit[@type=\"area-square-meter\"]/unitPattern[@count=\"other\"]"; 226 PathHeader ph1 = pathHeaderFactory.fromPath(p1); 227 PathHeader ph2 = pathHeaderFactory.fromPath(p2); 228 int comp12 = ph1.compareTo(ph2); 229 int comp21 = ph2.compareTo(ph1); 230 assertEquals("comp ph", comp12, -comp21); 231 } 232 TestVariant()233 public void TestVariant() { 234 PathHeader p1 = pathHeaderFactory 235 .fromPath("//ldml/localeDisplayNames/languages/language[@type=\"ug\"][@alt=\"variant\"]"); 236 PathHeader p2 = pathHeaderFactory 237 .fromPath("//ldml/localeDisplayNames/languages/language[@type=\"ug\"]"); 238 assertNotEquals("variants", p1, p2); 239 assertNotEquals("variants", p1.toString(), p2.toString()); 240 // Code Lists Languages Arabic Script ug-variant 241 } 242 Test4587()243 public void Test4587() { 244 String test = "//ldml/dates/timeZoneNames/metazone[@type=\"Pacific/Wallis\"]/short/standard"; 245 PathHeader ph = pathHeaderFactory.fromPath(test); 246 if (ph == null) { 247 errln("Failure with " + test); 248 } else { 249 logln(ph + "\t" + test); 250 } 251 } 252 TestMiscPatterns()253 public void TestMiscPatterns() { 254 String test = "//ldml/numbers/miscPatterns[@numberSystem=\"arab\"]/pattern[@type=\"atLeast\"]"; 255 PathHeader ph = pathHeaderFactory.fromPath(test); 256 assertNotNull("MiscPatterns path not found", ph); 257 if (false) 258 System.out.println(english.getStringValue(test)); 259 } 260 TestPluralOrder()261 public void TestPluralOrder() { 262 Set<PathHeader> sorted = new TreeSet<PathHeader>(); 263 for (String locale : new String[] { "ru", "ar", "ja" }) { 264 sorted.clear(); 265 CLDRFile cldrFile = info.getCLDRFile(locale, true); 266 CoverageLevel2 coverageLevel = CoverageLevel2.getInstance(locale); 267 for (String path : cldrFile.fullIterable()) { 268 if (!path.contains("@count")) { 269 continue; 270 } 271 Level level = coverageLevel.getLevel(path); 272 if (Level.MODERN.compareTo(level) < 0) { 273 continue; 274 } 275 PathHeader p = pathHeaderFactory.fromPath(path); 276 sorted.add(p); 277 } 278 for (PathHeader p : sorted) { 279 logln(locale + "\t" + p + "\t" + p.getOriginalPath()); 280 } 281 } 282 } 283 284 static final String APPEND_TIMEZONE = "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dateTimeFormats/appendItems/appendItem[@request=\"Timezone\"]"; 285 static final String APPEND_TIMEZONE_END = "/dateTimeFormats/appendItems/appendItem[@request=\"Timezone\"]"; 286 static final String BEFORE_PH = "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dateTimeFormats/availableFormats/dateFormatItem[@id=\"ms\"]"; 287 static final String AFTER_PH = "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dateTimeFormats/intervalFormats/intervalFormatItem[@id=\"d\"]/greatestDifference[@id=\"d\"]"; 288 TestAppendTimezone()289 public void TestAppendTimezone() { 290 CLDRFile cldrFile = info.getEnglish(); 291 CoverageLevel2 coverageLevel = CoverageLevel2.getInstance("en"); 292 assertEquals("appendItem:Timezone", Level.MODERATE, 293 coverageLevel.getLevel(APPEND_TIMEZONE)); 294 295 PathHeader ph = pathHeaderFactory.fromPath(APPEND_TIMEZONE); 296 assertEquals("appendItem:Timezone pathheader", "Timezone", ph.getCode()); 297 // check that they are in the right place (they weren't before!) 298 PathHeader phBefore = pathHeaderFactory.fromPath(BEFORE_PH); 299 PathHeader phAfter = pathHeaderFactory.fromPath(AFTER_PH); 300 assertTrue(phBefore, LEQ, ph); 301 assertTrue(ph, LEQ, phAfter); 302 303 PathDescription pathDescription = new PathDescription(supplemental, 304 english, null, null, PathDescription.ErrorHandling.CONTINUE); 305 String description = pathDescription.getDescription(APPEND_TIMEZONE, 306 "tempvalue", null, null); 307 assertTrue("appendItem:Timezone pathDescription", 308 description.contains("“Timezone”")); 309 310 PatternPlaceholders patternPlaceholders = PatternPlaceholders 311 .getInstance(); 312 PlaceholderStatus status = patternPlaceholders 313 .getStatus(APPEND_TIMEZONE); 314 assertEquals("appendItem:Timezone placeholders", 315 PlaceholderStatus.REQUIRED, status); 316 317 Map<String, PlaceholderInfo> placeholderInfo = patternPlaceholders 318 .get(APPEND_TIMEZONE); 319 PlaceholderInfo placeholderInfo2 = placeholderInfo.get("{1}"); 320 if (assertNotNull("appendItem:Timezone placeholders", placeholderInfo2)) { 321 assertEquals("appendItem:Timezone placeholders", 322 "APPEND_FIELD_FORMAT", placeholderInfo2.name); 323 assertEquals("appendItem:Timezone placeholders", "Pacific Time", 324 placeholderInfo2.example); 325 } 326 ExampleGenerator eg = new ExampleGenerator(cldrFile, cldrFile, 327 CLDRPaths.SUPPLEMENTAL_DIRECTORY); 328 String example = eg.getExampleHtml(APPEND_TIMEZONE, 329 cldrFile.getStringValue(APPEND_TIMEZONE)); 330 String result = ExampleGenerator.simplify(example, false); 331 assertEquals("", "〖❬6:25:59 PM❭ ❬GMT❭〗", result); 332 } 333 TestOptional()334 public void TestOptional() { 335 if (true) return; 336 Map<PathHeader, String> sorted = new TreeMap<PathHeader, String>(); 337 XPathParts parts = new XPathParts(); 338 for (String locale : new String[] { "af" }) { 339 sorted.clear(); 340 CLDRFile cldrFile = info.getCLDRFile(locale, true); 341 CoverageLevel2 coverageLevel = CoverageLevel2.getInstance(locale); 342 for (String path : cldrFile.fullIterable()) { 343 // if (!path.contains("@count")) { 344 // continue; 345 // } 346 Level level = coverageLevel.getLevel(path); 347 if (supplemental.isDeprecated(DtdType.ldml, path)) { 348 continue; 349 } 350 351 if (Level.OPTIONAL.compareTo(level) != 0) { 352 continue; 353 } 354 355 PathHeader p = pathHeaderFactory.fromPath(path); 356 final SurveyToolStatus status = p.getSurveyToolStatus(); 357 if (status == SurveyToolStatus.DEPRECATED) { 358 continue; 359 } 360 sorted.put( 361 p, 362 locale + "\t" + status + "\t" + p + "\t" 363 + p.getOriginalPath()); 364 } 365 Set<String> codes = new LinkedHashSet<String>(); 366 PathHeader old = null; 367 String line = null; 368 for (Entry<PathHeader, String> s : sorted.entrySet()) { 369 PathHeader p = s.getKey(); 370 String v = s.getValue(); 371 if (old == null) { 372 line = v; 373 codes.add(p.getCode()); 374 } else if (p.getSectionId() == old.getSectionId() 375 && p.getPageId() == old.getPageId() 376 && p.getHeader().equals(old.getHeader())) { 377 codes.add(p.getCode()); 378 } else { 379 logln(line + "\t" + codes.toString()); 380 codes.clear(); 381 line = v; 382 codes.add(p.getCode()); 383 } 384 old = p; 385 } 386 logln(line + "\t" + codes.toString()); 387 } 388 } 389 TestPluralCanonicals()390 public void TestPluralCanonicals() { 391 Relation<String, String> data = Relation.of( 392 new LinkedHashMap<String, Set<String>>(), TreeSet.class); 393 for (String locale : factory.getAvailable()) { 394 if (locale.contains("_")) { 395 continue; 396 } 397 PluralInfo info = supplemental.getPlurals(PluralType.cardinal, 398 locale); 399 Set<String> keywords = info.getCanonicalKeywords(); 400 data.put(keywords.toString(), locale); 401 } 402 for (Entry<String, Set<String>> entry : data.keyValuesSet()) { 403 logln(entry.getKey() + "\t" + entry.getValue()); 404 } 405 } 406 TestPluralPaths()407 public void TestPluralPaths() { 408 // do the following line once, when the file is opened 409 Set<String> filePaths = pathHeaderFactory.pathsForFile(english); 410 411 // check that English doesn't contain few or many 412 verifyContains(PageId.Duration, filePaths, "few", false); 413 verifyContains(PageId.C_NAmerica, filePaths, "many", false); 414 verifyContains(PageId.C_SAmerica, filePaths, "many", false); 415 verifyContains(PageId.C_NWEurope, filePaths, "many", false); 416 verifyContains(PageId.C_SEEurope, filePaths, "many", false); 417 verifyContains(PageId.C_NAfrica, filePaths, "many", false); 418 verifyContains(PageId.C_WAfrica, filePaths, "many", false); 419 verifyContains(PageId.C_SAfrica, filePaths, "many", false); 420 verifyContains(PageId.C_EAfrica, filePaths, "many", false); 421 verifyContains(PageId.C_CAsia, filePaths, "many", false); 422 verifyContains(PageId.C_WAsia, filePaths, "many", false); 423 verifyContains(PageId.C_SEAsia, filePaths, "many", false); 424 verifyContains(PageId.C_Oceania, filePaths, "many", false); 425 verifyContains(PageId.C_Unknown, filePaths, "many", false); 426 427 // check that Arabic does contain few and many 428 filePaths = pathHeaderFactory.pathsForFile(info.getCLDRFile("ar", true)); 429 430 verifyContains(PageId.Duration, filePaths, "few", true); 431 verifyContains(PageId.C_NAmerica, filePaths, "many", true); 432 verifyContains(PageId.C_SAmerica, filePaths, "many", true); 433 verifyContains(PageId.C_NWEurope, filePaths, "many", true); 434 verifyContains(PageId.C_SEEurope, filePaths, "many", true); 435 verifyContains(PageId.C_NAfrica, filePaths, "many", true); 436 verifyContains(PageId.C_WAfrica, filePaths, "many", true); 437 verifyContains(PageId.C_SAfrica, filePaths, "many", true); 438 verifyContains(PageId.C_EAfrica, filePaths, "many", true); 439 verifyContains(PageId.C_CAsia, filePaths, "many", true); 440 verifyContains(PageId.C_WAsia, filePaths, "many", true); 441 verifyContains(PageId.C_SEAsia, filePaths, "many", true); 442 verifyContains(PageId.C_Oceania, filePaths, "many", true); 443 verifyContains(PageId.C_Unknown, filePaths, "many", true); 444 } 445 TestCoverage()446 public void TestCoverage() { 447 Map<Row.R2<SectionId, PageId>, Counter<Level>> data = new TreeMap<Row.R2<SectionId, PageId>, Counter<Level>>(); 448 CLDRFile cldrFile = english; 449 for (String path : cldrFile.fullIterable()) { 450 if (supplemental.isDeprecated(DtdType.ldml, path)) { 451 errln("Deprecated path in English: " + path); 452 continue; 453 } 454 Level level = supplemental.getCoverageLevel(path, 455 cldrFile.getLocaleID()); 456 PathHeader p = pathHeaderFactory.fromPath(path); 457 SurveyToolStatus status = p.getSurveyToolStatus(); 458 459 boolean hideCoverage = level == Level.OPTIONAL; 460 boolean hidePathHeader = status == SurveyToolStatus.DEPRECATED 461 || status == SurveyToolStatus.HIDE; 462 if (hidePathHeader != hideCoverage) { 463 String message = "PathHeader: " + status + ", Coverage: " 464 + level + ": " + path; 465 if (hidePathHeader && !hideCoverage) { 466 errln(message); 467 } else if (!hidePathHeader && hideCoverage) { 468 logln(message); 469 } 470 } 471 final R2<SectionId, PageId> key = Row.of(p.getSectionId(), 472 p.getPageId()); 473 Counter<Level> counter = data.get(key); 474 if (counter == null) { 475 data.put(key, counter = new Counter<Level>()); 476 } 477 counter.add(level, 1); 478 } 479 StringBuffer b = new StringBuffer("\t"); 480 for (Level level : Level.values()) { 481 b.append("\t" + level); 482 } 483 logln(b.toString()); 484 for (Entry<R2<SectionId, PageId>, Counter<Level>> entry : data 485 .entrySet()) { 486 b.setLength(0); 487 b.append(entry.getKey().get0() + "\t" + entry.getKey().get1()); 488 Counter<Level> counter = entry.getValue(); 489 long total = 0; 490 for (Level level : Level.values()) { 491 total += counter.getCount(level); 492 b.append("\t" + total); 493 } 494 logln(b.toString()); 495 } 496 } 497 Test00AFile()498 public void Test00AFile() { 499 final String localeId = "en"; 500 Counter<Level> counter = new Counter<Level>(); 501 Map<String, PathHeader> uniqueness = new HashMap<String, PathHeader>(); 502 Set<String> alreadySeen = new HashSet<String>(); 503 check(localeId, true, uniqueness, alreadySeen); 504 // check paths 505 for (Entry<SectionId, Set<PageId>> sectionAndPages : PathHeader.Factory 506 .getSectionIdsToPageIds().keyValuesSet()) { 507 final SectionId section = sectionAndPages.getKey(); 508 if (section == SectionId.Supplemental || section == SectionId.BCP47) { 509 continue; 510 } 511 logln(section.toString()); 512 for (PageId page : sectionAndPages.getValue()) { 513 final Set<String> cachedPaths = PathHeader.Factory 514 .getCachedPaths(section, page); 515 if (cachedPaths == null) { 516 if (!badZonePages.contains(page) && page != PageId.Unknown) { 517 errln("Null pages for: " + section + "\t" + page); 518 } 519 } else if (section == SectionId.Special 520 && page == PageId.Unknown) { 521 // skip 522 } else if (section == SectionId.Timezones 523 && page == PageId.UnknownT) { 524 // skip 525 } else if (section == SectionId.Misc 526 && page == PageId.Transforms) { 527 // skip 528 } else { 529 530 int count2 = cachedPaths.size(); 531 if (count2 == 0) { 532 warnln("Missing pages for: " + section + "\t" + page); 533 } else { 534 counter.clear(); 535 for (String s : cachedPaths) { 536 Level coverage = supplemental.getCoverageLevel(s, 537 localeId); 538 counter.add(coverage, 1); 539 } 540 String countString = ""; 541 int total = 0; 542 for (Level item : Level.values()) { 543 long count = counter.get(item); 544 if (count != 0) { 545 if (!countString.isEmpty()) { 546 countString += ",\t+"; 547 } 548 total += count; 549 countString += item + "=" + total; 550 } 551 } 552 logln("\t" + page + "\t" + countString); 553 if (page.toString().startsWith("Unknown")) { 554 logln("\t\t" + cachedPaths); 555 } 556 } 557 } 558 } 559 } 560 } 561 TestMetazones()562 public void TestMetazones() { 563 564 CLDRFile nativeFile = info.getEnglish(); 565 Set<PathHeader> pathHeaders = getPathHeaders(nativeFile); 566 // String oldPage = ""; 567 String oldHeader = ""; 568 for (PathHeader entry : pathHeaders) { 569 final String page = entry.getPage(); 570 // if (!oldPage.equals(page)) { 571 // logln(page); 572 // oldPage = page; 573 // } 574 String header = entry.getHeader(); 575 if (!oldHeader.equals(header)) { 576 logln(page + "\t" + header); 577 oldHeader = header; 578 } 579 } 580 } 581 getPathHeaders(CLDRFile nativeFile)582 public Set<PathHeader> getPathHeaders(CLDRFile nativeFile) { 583 Set<PathHeader> pathHeaders = new TreeSet<PathHeader>(); 584 for (String path : nativeFile.fullIterable()) { 585 PathHeader p = pathHeaderFactory.fromPath(path); 586 pathHeaders.add(p); 587 } 588 return pathHeaders; 589 } 590 verifyContains(PageId pageId, Set<String> filePaths, String substring, boolean contains)591 public void verifyContains(PageId pageId, Set<String> filePaths, 592 String substring, boolean contains) { 593 String path; 594 path = findOneContaining(allPaths(pageId, filePaths), substring); 595 if (contains) { 596 if (path == null) { 597 errln("No path contains <" + substring + ">"); 598 } 599 } else { 600 if (path != null) { 601 errln("Path contains <" + substring + ">\t" + path); 602 } 603 } 604 } 605 findOneContaining(Collection<String> allPaths, String substring)606 private String findOneContaining(Collection<String> allPaths, 607 String substring) { 608 for (String path : allPaths) { 609 if (path.contains(substring)) { 610 return path; 611 } 612 } 613 return null; 614 } 615 allPaths(PageId pageId, Set<String> filePaths)616 public Set<String> allPaths(PageId pageId, Set<String> filePaths) { 617 Set<String> result = PathHeader.Factory.getCachedPaths( 618 pageId.getSectionId(), pageId); 619 result.retainAll(filePaths); 620 return result; 621 } 622 TestUniqueness()623 public void TestUniqueness() { 624 CLDRFile nativeFile = info.getEnglish(); 625 Map<PathHeader, String> headerToPath = new HashMap<PathHeader, String>(); 626 Map<String, String> headerVisibleToPath = new HashMap<String, String>(); 627 for (String path : nativeFile.fullIterable()) { 628 PathHeader p = pathHeaderFactory.fromPath(path); 629 if (p.getSectionId() == SectionId.Special) { 630 continue; 631 } 632 String old = headerToPath.get(p); 633 if (old == null) { 634 headerToPath.put(p, path); 635 } else if (!old.equals(path)) { 636 if (true) { // for debugging 637 pathHeaderFactory.clearCache(); 638 List<String> failuresOld = new ArrayList<>(); 639 pathHeaderFactory.fromPath(old, failuresOld); 640 List<String> failuresPath = new ArrayList<>(); 641 pathHeaderFactory.fromPath(path, failuresPath); 642 } 643 errln("Collision with path " + p + "\t" + old + "\t" + path); 644 } 645 final String visible = p.toString(); 646 old = headerVisibleToPath.get(visible); 647 if (old == null) { 648 headerVisibleToPath.put(visible, path); 649 } else if (!old.equals(path)) { 650 errln("Collision with path " + visible + "\t" + old + "\t" 651 + path); 652 } 653 } 654 } 655 TestStatus()656 public void TestStatus() { 657 CLDRFile nativeFile = info.getEnglish(); 658 PathStarrer starrer = new PathStarrer(); 659 EnumMap<SurveyToolStatus, Relation<String, String>> info2 = new EnumMap<SurveyToolStatus, Relation<String, String>>( 660 SurveyToolStatus.class); 661 Set<String> nuked = new HashSet<String>(); 662 PrettyPath pp = new PrettyPath(); 663 XPathParts parts = new XPathParts(); 664 Set<String> deprecatedStar = new HashSet<String>(); 665 Set<String> differentStar = new HashSet<String>(); 666 667 for (String path : nativeFile.fullIterable()) { 668 669 PathHeader p = pathHeaderFactory.fromPath(path); 670 final SurveyToolStatus surveyToolStatus = p.getSurveyToolStatus(); 671 672 if (p.getSectionId() == SectionId.Special 673 && surveyToolStatus == SurveyToolStatus.READ_WRITE) { 674 errln("SurveyToolStatus should not be " + surveyToolStatus 675 + ": " + p); 676 } 677 678 final SurveyToolStatus tempSTS = surveyToolStatus == SurveyToolStatus.DEPRECATED ? SurveyToolStatus.HIDE 679 : surveyToolStatus; 680 String starred = starrer.set(path); 681 List<String> attr = starrer.getAttributes(); 682 if (surveyToolStatus != SurveyToolStatus.READ_WRITE) { 683 nuked.add(starred); 684 } 685 686 // check against old 687 SurveyToolStatus oldStatus = SurveyToolStatus.READ_WRITE; 688 689 if (tempSTS != oldStatus 690 && oldStatus != SurveyToolStatus.READ_WRITE 691 && !path.endsWith(APPEND_TIMEZONE_END)) { 692 if (!differentStar.contains(starred)) { 693 errln("Different from old:\t" + oldStatus + "\tnew:\t" 694 + surveyToolStatus + "\t" + path); 695 differentStar.add(starred); 696 } 697 } 698 699 // check against deprecated 700 boolean isDeprecated = supplemental.isDeprecated(DtdType.ldml, path); 701 if (isDeprecated != (surveyToolStatus == SurveyToolStatus.DEPRECATED)) { 702 if (!deprecatedStar.contains(starred)) { 703 errln("Different from DtdData deprecated:\t" 704 + isDeprecated + "\t" + surveyToolStatus + "\t" 705 + path); 706 deprecatedStar.add(starred); 707 } 708 } 709 710 Relation<String, String> data = info2.get(surveyToolStatus); 711 if (data == null) { 712 info2.put( 713 surveyToolStatus, 714 data = Relation.of(new TreeMap<String, Set<String>>(), 715 TreeSet.class)); 716 } 717 data.put(starred, CollectionUtilities.join(attr, "|")); 718 } 719 for (Entry<SurveyToolStatus, Relation<String, String>> entry : info2 720 .entrySet()) { 721 final SurveyToolStatus status = entry.getKey(); 722 for (Entry<String, Set<String>> item : entry.getValue() 723 .keyValuesSet()) { 724 final String starred = item.getKey(); 725 if (status == SurveyToolStatus.READ_WRITE 726 && !nuked.contains(starred)) { 727 continue; 728 } 729 logln(status + "\t" + starred + "\t" + item.getValue()); 730 } 731 } 732 } 733 TestPathsNotInEnglish()734 public void TestPathsNotInEnglish() { 735 Set<String> englishPaths = new HashSet<String>(); 736 for (String path : english.fullIterable()) { 737 englishPaths.add(path); 738 } 739 Set<String> alreadySeen = new HashSet<String>(englishPaths); 740 741 for (String locale : factory.getAvailable()) { 742 CLDRFile nativeFile = info.getCLDRFile(locale, false); 743 CoverageLevel2 coverageLevel2 = null; 744 for (String path : nativeFile.fullIterable()) { 745 if (alreadySeen.contains(path) || path.contains("@count")) { 746 continue; 747 } 748 if (coverageLevel2 == null) { 749 coverageLevel2 = CoverageLevel2.getInstance(locale); 750 } 751 Level level = coverageLevel2.getLevel(path); 752 if (Level.COMPREHENSIVE.compareTo(level) < 0) { 753 continue; 754 } 755 logln("Path not in English\t" + locale + "\t" + path); 756 alreadySeen.add(path); 757 } 758 } 759 } 760 TestPathDescriptionCompleteness()761 public void TestPathDescriptionCompleteness() { 762 PathDescription pathDescription = new PathDescription(supplemental, 763 english, null, null, PathDescription.ErrorHandling.CONTINUE); 764 Matcher normal = PatternCache.get( 765 "http://cldr.org/translation/[a-zA-Z0-9_]").matcher(""); 766 // http://cldr.unicode.org/translation/plurals#TOC-Minimal-Pairs 767 Set<String> alreadySeen = new HashSet<String>(); 768 PathStarrer starrer = new PathStarrer(); 769 770 checkPathDescriptionCompleteness(pathDescription, normal, 771 "//ldml/numbers/defaultNumberingSystem", alreadySeen, starrer); 772 for (PathHeader pathHeader : getPathHeaders(english)) { 773 final SurveyToolStatus surveyToolStatus = pathHeader 774 .getSurveyToolStatus(); 775 if (surveyToolStatus == SurveyToolStatus.DEPRECATED 776 || surveyToolStatus == SurveyToolStatus.HIDE) { 777 continue; 778 } 779 String path = pathHeader.getOriginalPath(); 780 checkPathDescriptionCompleteness(pathDescription, normal, path, 781 alreadySeen, starrer); 782 } 783 } 784 checkPathDescriptionCompleteness( PathDescription pathDescription, Matcher normal, String path, Set<String> alreadySeen, PathStarrer starrer)785 public void checkPathDescriptionCompleteness( 786 PathDescription pathDescription, Matcher normal, String path, 787 Set<String> alreadySeen, PathStarrer starrer) { 788 String value = english.getStringValue(path); 789 String description = pathDescription.getDescription(path, value, null, 790 null); 791 String starred = starrer.set(path); 792 if (alreadySeen.contains(starred)) { 793 return; 794 } else if (description == null) { 795 errln("Path has no description:\t" + value + "\t" + path); 796 } else if (!description.contains("http://")) { 797 errln("Description has no URL:\t" + description + "\t" + value 798 + "\t" + path); 799 } else if (!normal.reset(description).find()) { 800 errln("Description has generic URL, fix to be specific:\t" 801 + description + "\t" + value + "\t" + path); 802 } else if (description == PathDescription.MISSING_DESCRIPTION) { 803 errln("Fallback Description:\t" + value + "\t" + path); 804 } else { 805 return; 806 } 807 // Add if we had a problem, keeping us from being overwhelmed with 808 // errors. 809 alreadySeen.add(starred); 810 } 811 TestTerritoryOrder()812 public void TestTerritoryOrder() { 813 final Set<String> goodAvailableCodes = CLDRConfig.getInstance() 814 .getStandardCodes().getGoodAvailableCodes("territory"); 815 Set<String> results = showContained("001", 0, new HashSet<String>( 816 goodAvailableCodes)); 817 results.remove("ZZ"); 818 for (String territory : results) { 819 String sub = Containment.getSubcontinent(territory); 820 String cont = Containment.getContinent(territory); 821 errln("Missing\t" + getNameAndOrder(territory) + "\t" 822 + getNameAndOrder(sub) + "\t" + getNameAndOrder(cont)); 823 } 824 } 825 showContained(String territory, int level, Set<String> soFar)826 private Set<String> showContained(String territory, int level, 827 Set<String> soFar) { 828 if (!soFar.contains(territory)) { 829 return soFar; 830 } 831 soFar.remove(territory); 832 Set<String> contained = supplemental.getContained(territory); 833 if (contained == null) { 834 return soFar; 835 } 836 for (String containedItem : contained) { 837 logln(level + "\t" + getNameAndOrder(territory) + "\t" 838 + getNameAndOrder(containedItem)); 839 } 840 for (String containedItem : contained) { 841 showContained(containedItem, level + 1, soFar); 842 } 843 return soFar; 844 } 845 getNameAndOrder(String territory)846 private String getNameAndOrder(String territory) { 847 return territory + "\t" 848 + english.getName(CLDRFile.TERRITORY_NAME, territory) + "\t" 849 + Containment.getOrder(territory); 850 } 851 TestZCompleteness()852 public void TestZCompleteness() { 853 Map<String, PathHeader> uniqueness = new HashMap<String, PathHeader>(); 854 Set<String> alreadySeen = new HashSet<String>(); 855 LanguageTagParser ltp = new LanguageTagParser(); 856 int count = 0; 857 for (String locale : factory.getAvailable()) { 858 if (!ltp.set(locale).getRegion().isEmpty()) { 859 continue; 860 } 861 check(locale, false, uniqueness, alreadySeen); 862 ++count; 863 } 864 logln("Count:\t" + count); 865 } 866 check(String localeID, boolean resolved, Map<String, PathHeader> uniqueness, Set<String> alreadySeen)867 public void check(String localeID, boolean resolved, 868 Map<String, PathHeader> uniqueness, Set<String> alreadySeen) { 869 CLDRFile nativeFile = info.getCLDRFile(localeID, resolved); 870 int count = 0; 871 for (String path : nativeFile) { 872 if (alreadySeen.contains(path)) { 873 continue; 874 } 875 alreadySeen.add(path); 876 final PathHeader pathHeader = pathHeaderFactory.fromPath(path); 877 ++count; 878 if (pathHeader == null) { 879 errln("Null pathheader for " + path); 880 } else { 881 String visible = pathHeader.toString(); 882 PathHeader old = uniqueness.get(visible); 883 if (pathHeader.getSectionId() == SectionId.Timezones) { 884 final PageId pageId = pathHeader.getPageId(); 885 if (badZonePages.contains(pageId) 886 && !pathHeader.getCode().equals("Unknown")) { 887 String msg = "Bad page ID:\t" + pageId + "\t" + pathHeader + "\t" + path; 888 if (!logKnownIssue("cldrbug:7802", "ICU/CLDR time zone data sync problem - " + msg)) { 889 errln("Bad page ID:\t" + pageId + "\t" + pathHeader 890 + "\t" + path); 891 } 892 } 893 } 894 if (old == null) { 895 if (pathHeader.getSection().equals("Special")) { 896 if (pathHeader.getSection().equals("Unknown")) { 897 errln("PathHeader has fallback: " + visible + "\t" 898 + pathHeader.getOriginalPath()); 899 // } else { 900 // logln("Special:\t" + visible + "\t" + 901 // pathHeader.getOriginalPath()); 902 } 903 } 904 uniqueness.put(visible, pathHeader); 905 } else if (!old.equals(pathHeader)) { 906 if (pathHeader.getSectionId() == SectionId.Special) { 907 logln("Special PathHeader not unique: " + visible 908 + "\t" + pathHeader.getOriginalPath() + "\t" 909 + old.getOriginalPath()); 910 } else { 911 errln("PathHeader not unique: " + visible + "\t" 912 + pathHeader.getOriginalPath() + "\t" 913 + old.getOriginalPath()); 914 } 915 } 916 } 917 } 918 logln(localeID + "\t" + count); 919 } 920 TestContainment()921 public void TestContainment() { 922 Map<String, Map<String, String>> metazoneToRegionToZone = supplemental 923 .getMetazoneToRegionToZone(); 924 Map<String, String> metazoneToContinent = supplemental 925 .getMetazoneToContinentMap(); 926 for (String metazone : metazoneToRegionToZone.keySet()) { 927 Map<String, String> regionToZone = metazoneToRegionToZone 928 .get(metazone); 929 String worldZone = regionToZone.get("001"); 930 String territory = Containment.getRegionFromZone(worldZone); 931 if (territory == null) { 932 territory = "ZZ"; 933 } 934 String cont = Containment.getContinent(territory); 935 int order = Containment.getOrder(territory); 936 String sub = Containment.getSubcontinent(territory); 937 String revision = PathHeader.getMetazonePageTerritory(metazone); 938 String continent = metazoneToContinent.get(metazone); 939 if (continent == null) { 940 continent = "UnknownT"; 941 } 942 // Russia, Antarctica => territory 943 // in Australasia, Asia, S. America => subcontinent 944 // in N. America => N. America (grouping of 3 subcontinents) 945 // in everything else => continent 946 947 if (territory.equals("RU")) { 948 assertEquals("Russia special case", "RU", revision); 949 } else if (territory.equals("US")) { 950 assertEquals("N. America special case", "003", revision); 951 } else if (territory.equals("BR")) { 952 assertEquals("S. America special case", "005", revision); 953 } 954 if (isVerbose()) { 955 String name = english.getName(CLDRFile.TERRITORY_NAME, cont); 956 String name2 = english.getName(CLDRFile.TERRITORY_NAME, sub); 957 String name3 = english.getName(CLDRFile.TERRITORY_NAME, 958 territory); 959 String name4 = english.getName(CLDRFile.TERRITORY_NAME, 960 revision); 961 962 logln(metazone + "\t" + continent + "\t" + name + "\t" + name2 963 + "\t" + name3 + "\t" + order + "\t" + name4); 964 } 965 } 966 } 967 TestZ()968 public void TestZ() { 969 PathStarrer pathStarrer = new PathStarrer(); 970 pathStarrer.setSubstitutionPattern("%A"); 971 972 Set<PathHeader> sorted = new TreeSet<PathHeader>(); 973 Map<String, String> missing = new TreeMap<String, String>(); 974 Map<String, String> skipped = new TreeMap<String, String>(); 975 Map<String, String> collide = new TreeMap<String, String>(); 976 977 logln("Traversing Paths"); 978 for (String path : english) { 979 PathHeader pathHeader = pathHeaderFactory.fromPath(path); 980 String value = english.getStringValue(path); 981 if (pathHeader == null) { 982 final String starred = pathStarrer.set(path); 983 missing.put(starred, value + "\t" + path); 984 continue; 985 } 986 if (pathHeader.getSection().equalsIgnoreCase("skip")) { 987 final String starred = pathStarrer.set(path); 988 skipped.put(starred, value + "\t" + path); 989 continue; 990 } 991 sorted.add(pathHeader); 992 } 993 logln("\nConverted:\t" + sorted.size()); 994 String lastHeader = ""; 995 String lastPage = ""; 996 String lastSection = ""; 997 List<String> threeLevel = new ArrayList<String>(); 998 Status status = new Status(); 999 CoverageLevel2 coverageLevel2 = CoverageLevel2.getInstance("en"); 1000 1001 for (PathHeader pathHeader : sorted) { 1002 String original = pathHeader.getOriginalPath(); 1003 if (!original.equals(status.pathWhereFound)) { 1004 continue; 1005 } 1006 if (!lastSection.equals(pathHeader.getSection())) { 1007 logln(""); 1008 threeLevel.add(pathHeader.getSection()); 1009 threeLevel.add("\t" + pathHeader.getPage()); 1010 threeLevel.add("\t\t" + pathHeader.getHeader()); 1011 lastSection = pathHeader.getSection(); 1012 lastPage = pathHeader.getPage(); 1013 lastHeader = pathHeader.getHeader(); 1014 } else if (!lastPage.equals(pathHeader.getPage())) { 1015 logln(""); 1016 threeLevel.add("\t" + pathHeader.getPage()); 1017 threeLevel.add("\t\t" + pathHeader.getHeader()); 1018 lastPage = pathHeader.getPage(); 1019 lastHeader = pathHeader.getHeader(); 1020 } else if (!lastHeader.equals(pathHeader.getHeader())) { 1021 logln(""); 1022 threeLevel.add("\t\t" + pathHeader.getHeader()); 1023 lastHeader = pathHeader.getHeader(); 1024 } 1025 logln(pathHeader + "\t" + coverageLevel2.getLevel(original) + "\t" 1026 + english.getStringValue(pathHeader.getOriginalPath()) 1027 + "\t" + pathHeader.getOriginalPath()); 1028 } 1029 if (collide.size() != 0) { 1030 errln("\nCollide:\t" + collide.size()); 1031 for (Entry<String, String> item : collide.entrySet()) { 1032 errln("\t" + item); 1033 } 1034 } 1035 if (missing.size() != 0) { 1036 errln("\nMissing:\t" + missing.size()); 1037 for (Entry<String, String> item : missing.entrySet()) { 1038 errln("\t" + item.getKey() + "\tvalue:\t" + item.getValue()); 1039 } 1040 } 1041 if (skipped.size() != 0) { 1042 errln("\nSkipped:\t" + skipped.size()); 1043 for (Entry<String, String> item : skipped.entrySet()) { 1044 errln("\t" + item); 1045 } 1046 } 1047 Counter<PathHeader.Factory.CounterData> counterData = pathHeaderFactory 1048 .getInternalCounter(); 1049 logln("\nInternal Counter:\t" + counterData.size()); 1050 for (PathHeader.Factory.CounterData item : counterData.keySet()) { 1051 logln("\t" + counterData.getCount(item) + "\t" + item.get2() // externals 1052 + "\t" + item.get3() + "\t" + item.get0() // internals 1053 + "\t" + item.get1()); 1054 } 1055 logln("\nMenus/Headers:\t" + threeLevel.size()); 1056 for (String item : threeLevel) { 1057 logln(item); 1058 } 1059 LinkedHashMap<String, Set<String>> sectionsToPages = pathHeaderFactory 1060 .getSectionsToPages(); 1061 logln("\nMenus:\t" + sectionsToPages.size()); 1062 for (Entry<String, Set<String>> item : sectionsToPages.entrySet()) { 1063 final String section = item.getKey(); 1064 for (String page : item.getValue()) { 1065 logln("\t" + section + "\t" + page); 1066 int count = 0; 1067 for (String path : pathHeaderFactory.filterCldr(section, page, 1068 english)) { 1069 count += 1; // just count them. 1070 } 1071 logln("\t" + count); 1072 } 1073 } 1074 } 1075 TestOrder()1076 public void TestOrder() { 1077 String[] paths = { 1078 "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dayPeriods/dayPeriodContext[@type=\"format\"]/dayPeriodWidth[@type=\"narrow\"]/dayPeriod[@type=\"noon\"]", 1079 "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dayPeriods/dayPeriodContext[@type=\"format\"]/dayPeriodWidth[@type=\"narrow\"]/dayPeriod[@type=\"afternoon1\"]", 1080 }; 1081 PathHeader pathHeaderLast = null; 1082 for (String path : paths) { 1083 PathHeader pathHeader = pathHeaderFactory.fromPath(path); 1084 if (pathHeaderLast != null) { 1085 assertRelation("ordering", true, pathHeaderLast, LEQ, pathHeader); 1086 } 1087 pathHeaderLast = pathHeader; 1088 } 1089 1090 } 1091 Test8414()1092 public void Test8414() { 1093 PathDescription pathDescription = new PathDescription(supplemental, 1094 english, null, null, PathDescription.ErrorHandling.CONTINUE); 1095 1096 String prefix = "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dayPeriods/dayPeriodContext[@type=\""; 1097 String suffix = "\"]/dayPeriodWidth[@type=\"wide\"]/dayPeriod[@type=\"morning1\"]"; 1098 1099 final String path0 = prefix + "format" + suffix; 1100 final String path1 = prefix + "stand-alone" + suffix; 1101 String v0 = english.getStringValue(path0); 1102 String v1 = english.getStringValue(path1); 1103 String p0 = pathDescription.getDescription(path0, v0, null, null); 1104 String p1 = pathDescription.getDescription(path1, v1, null, null); 1105 assertTrue("Check pd for format", p0.contains("in the morning")); 1106 assertTrue("Check pd for stand-alone", !p1.contains("in the morning")); 1107 } 1108 TestCompletenessNonLdmlDtd()1109 public void TestCompletenessNonLdmlDtd() { 1110 PathChecker pathChecker = new PathChecker(); 1111 Set<String> directories = new LinkedHashSet<>(); 1112 XPathParts parts = new XPathParts(); 1113 Multimap<String, String> pathValuePairs = LinkedListMultimap.create(); 1114 // get all the directories containing non-Ldml dtd files 1115 for (DtdType dtdType : DtdType.values()) { 1116 if (dtdType == DtdType.ldml || dtdType == DtdType.ldmlICU) { 1117 continue; 1118 } 1119 DtdData dtdData = DtdData.getInstance(dtdType); 1120 for (String dir : dtdType.directories) { 1121 if (DEBUG_DTD_TYPE != null && !DEBUG_DTD_TYPE.directories.contains(dir)) { 1122 continue; 1123 } 1124 File dir2 = new File(COMMON_DIR + dir); 1125 logln(dir2.getName()); 1126 for (String file : dir2.list()) { 1127 // don't need to restrict with getFilesToTest(Arrays.asList(dir2.list()), "root", "en")) { 1128 if (!file.endsWith(".xml")) { 1129 continue; 1130 } 1131 if (DEBUG) warnln(" TestCompletenessNonLdmlDtd: " + dir + ", " + file); 1132 logln(" \t" + file); 1133 for (Pair<String, String> pathValue : XMLFileReader.loadPathValues( 1134 dir2 + "/" + file, new ArrayList<Pair<String, String>>(), true)) { 1135 final String path = pathValue.getFirst(); 1136 final String value = pathValue.getSecond(); 1137 // logln("\t\t" + path); 1138 if (path.startsWith("//supplementalData/weekData/weekOf")) { 1139 int debug = 0; 1140 } 1141 pathChecker.checkPathHeader(dtdData, path); 1142 } 1143 ; 1144 } 1145 } 1146 } 1147 } 1148 1149 private class PathChecker { 1150 PathHeader.Factory phf = pathHeaderFactory; 1151 PathStarrer starrer = new PathStarrer().setSubstitutionPattern("%A"); 1152 1153 Set<String> badHeaders = new TreeSet<>(); 1154 Map<PathHeader, PathHeader> goodHeaders = new HashMap<>(); 1155 Set<PathHeader> seenBad = new HashSet<>(); 1156 { phf.clearCache()1157 phf.clearCache(); 1158 } 1159 checkPathHeader(DtdData dtdData, String rawPath)1160 public void checkPathHeader(DtdData dtdData, String rawPath) { 1161 XPathParts pathPlain = XPathParts.getFrozenInstance(rawPath); 1162 if (dtdData.isMetadata(pathPlain)) { 1163 return; 1164 } 1165 if (dtdData.isDeprecated(pathPlain)) { 1166 return; 1167 } 1168 Multimap<String, String> extras = HashMultimap.create(); 1169 Set<String> fixedPaths = dtdData.getRegularizedPaths(pathPlain, extras); 1170 if (fixedPaths != null) { 1171 for (String fixedPath : fixedPaths) { 1172 checkSubpath(fixedPath); 1173 } 1174 } 1175 for (String path : extras.keySet()) { 1176 checkSubpath(path); 1177 } 1178 } 1179 checkSubpath(String path)1180 public void checkSubpath(String path) { 1181 String message = ": Can't compute path header"; 1182 PathHeader ph = null; 1183 try { 1184 ph = phf.fromPath(path); 1185 if (seenBad.contains(ph)) { 1186 return; 1187 } 1188 if (ph.getPageId() == PageId.Deprecated) { 1189 return; // don't care 1190 } 1191 if (ph.getPageId() != PageId.Unknown) { 1192 PathHeader old = goodHeaders.put(ph, ph); 1193 if (old != null && !path.equals(old.getOriginalPath())) { 1194 errln("Duplicate path header for: " + ph 1195 + "\n\t\t " + path 1196 + "\n\t\t≠" + old.getOriginalPath()); 1197 seenBad.add(ph); 1198 } 1199 return; 1200 } 1201 // for debugging 1202 phf.clearCache(); 1203 List<String> failures = new ArrayList<>(); 1204 ph = phf.fromPath(path, failures); 1205 message = ": Unknown path header" + failures; 1206 } catch (Exception e) { 1207 message = ": Exception in path header: " + e.getMessage(); 1208 } 1209 String star = starrer.set(path); 1210 if (badHeaders.add(star)) { 1211 errln(star + message + ", " + ph); 1212 } 1213 } 1214 } 1215 TestSupplementalItems()1216 public void TestSupplementalItems() { 1217 // <weekOfPreference ordering="weekOfYear weekOfMonth" locales="am az bs cs cy da el et hi ky lt mk sk ta th"/> 1218 // logln(pathHeaderFactory.getRegexInfo()); 1219 CLDRFile supplementalFile = CLDRConfig.getInstance().getSupplementalFactory().make("supplementalData", false); 1220 List<String> failures = new ArrayList<>(); 1221 Multimap<String, String> pathValuePairs = LinkedListMultimap.create(); 1222 XPathParts parts = new XPathParts(); 1223 for (String test : With.in(supplementalFile.iterator("//supplementalData/weekData"))) { 1224 failures.clear(); 1225 supplementalFile.getDtdData().getRegularizedPaths(parts.set(supplementalFile.getFullXPath(test)), pathValuePairs); 1226 for (Entry<String, Collection<String>> entry : pathValuePairs.asMap().entrySet()) { 1227 final String normalizedPath = entry.getKey(); 1228 final Collection<String> normalizedValue = entry.getValue(); 1229 PathHeader ph = pathHeaderFactory.fromPath(normalizedPath, failures); 1230 if (ph == null || ph.getSectionId() == SectionId.Special) { 1231 errln("Failure with " + test + " => " + normalizedPath + " = " + normalizedValue); 1232 } else { 1233 logln(ph + "\t" + test + " = " + normalizedValue); 1234 } 1235 } 1236 } 1237 } 1238 test10232()1239 public void test10232() { 1240 String[][] tests = { 1241 { "MMM", "Formats - Flexible - Date Formats" }, 1242 { "dMM", "Formats - Flexible - Date Formats" }, 1243 { "h", "Formats - Flexible - 12 Hour Time Formats" }, 1244 { "hm", "Formats - Flexible - 12 Hour Time Formats" }, 1245 { "Ehm", "Formats - Flexible - 12 Hour Time Formats" }, 1246 { "H", "Formats - Flexible - 24 Hour Time Formats" }, 1247 { "Hm", "Formats - Flexible - 24 Hour Time Formats" }, 1248 { "EHm", "Formats - Flexible - 24 Hour Time Formats" }, 1249 }; 1250 for (String[] test : tests) { 1251 String path = "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dateTimeFormats/availableFormats/dateFormatItem[@id=\"" 1252 + test[0] + "\"]"; 1253 PathHeader pathHeader = pathHeaderFactory.fromPath(path); 1254 assertEquals("flexible formats", test[1] + "|" + test[0], pathHeader.getHeader() + "|" + pathHeader.getCode()); 1255 } 1256 } 1257 1258 // Moved from TestAnnotations and generalized testPathHeaderSize()1259 public void testPathHeaderSize() { 1260 String locale = "ar"; // choose one with lots of plurals 1261 int maxSize = 700; 1262 boolean showTable = false; // only printed if test fails or verbose 1263 1264 Factory factory = CLDRConfig.getInstance().getCommonAndSeedAndMainAndAnnotationsFactory(); 1265 CLDRFile english = factory.make(locale, true); 1266 1267 PathHeader.Factory phf = PathHeader.getFactory(CLDRConfig.getInstance().getEnglish()); 1268 Counter<PageId> counterPageId = new Counter<>(); 1269 Counter<PageId> counterPageIdAll = new Counter<>(); 1270 for (String path : english) { 1271 Level level = CLDRConfig.getInstance().getSupplementalDataInfo().getCoverageLevel(path, locale); 1272 PathHeader ph = phf.fromPath(path); 1273 if (level.compareTo(Level.MODERN) <= 0) { 1274 counterPageId.add(ph.getPageId(), 1); 1275 } 1276 counterPageIdAll.add(ph.getPageId(), 1); 1277 } 1278 Set<R2<Long, PageId>> entrySetSortedByCount = counterPageId.getEntrySetSortedByCount(false, null); 1279 for (R2<Long, PageId> sizeAndPageId : entrySetSortedByCount) { 1280 long size = sizeAndPageId.get0(); 1281 PageId pageId = sizeAndPageId.get1(); 1282 if (!assertTrue(pageId.getSectionId() + "/" + pageId + " size (" + size 1283 + ") < " + maxSize + "?", size < maxSize)) { 1284 showTable = true; 1285 } 1286 // System.out.println(pageId + "\t" + size); 1287 } 1288 if (showTable || isVerbose()) { 1289 for (R2<Long, PageId> sizeAndPageId : entrySetSortedByCount) { 1290 PageId pageId = sizeAndPageId.get1(); 1291 System.out.println(pageId.getSectionId() + "\t" + pageId + "\t" + sizeAndPageId.get0() + "\t" + counterPageIdAll.get(pageId)); 1292 } 1293 } 1294 } 1295 } 1296