1 package org.unicode.cldr.unittest; 2 3 import java.util.ArrayList; 4 import java.util.Arrays; 5 import java.util.HashMap; 6 import java.util.HashSet; 7 import java.util.LinkedHashMap; 8 import java.util.List; 9 import java.util.Map; 10 import java.util.Set; 11 import java.util.TreeSet; 12 import java.util.regex.Matcher; 13 14 import org.unicode.cldr.test.CheckCLDR; 15 import org.unicode.cldr.test.CheckCLDR.CheckStatus; 16 import org.unicode.cldr.test.CheckCLDR.CheckStatus.Subtype; 17 import org.unicode.cldr.test.CheckCLDR.Options; 18 import org.unicode.cldr.test.CheckConsistentCasing; 19 import org.unicode.cldr.test.CheckDates; 20 import org.unicode.cldr.test.CheckForExemplars; 21 import org.unicode.cldr.test.CheckNames; 22 import org.unicode.cldr.test.CheckNew; 23 import org.unicode.cldr.util.CLDRConfig; 24 import org.unicode.cldr.util.CLDRFile; 25 import org.unicode.cldr.util.DayPeriodInfo; 26 import org.unicode.cldr.util.DayPeriodInfo.DayPeriod; 27 import org.unicode.cldr.util.DayPeriodInfo.Type; 28 import org.unicode.cldr.util.Factory; 29 import org.unicode.cldr.util.LanguageTagParser; 30 import org.unicode.cldr.util.PathHeader; 31 import org.unicode.cldr.util.PatternCache; 32 import org.unicode.cldr.util.PatternPlaceholders; 33 import org.unicode.cldr.util.PatternPlaceholders.PlaceholderInfo; 34 import org.unicode.cldr.util.PatternPlaceholders.PlaceholderStatus; 35 import org.unicode.cldr.util.SimpleXMLSource; 36 import org.unicode.cldr.util.StringId; 37 38 import com.ibm.icu.dev.test.TestFmwk; 39 import com.ibm.icu.text.UnicodeSet; 40 41 public class TestCheckCLDR extends TestFmwk { 42 static CLDRConfig testInfo = CLDRConfig.getInstance(); 43 private final Set<String> eightPointLocales = new TreeSet<String>( 44 Arrays.asList("ar ca cs da de el es fi fr he hi hr hu id it ja ko lt lv nb nl pl pt pt_PT ro ru sk sl sr sv th tr uk vi zh zh_Hant".split(" "))); 45 46 public static void main(String[] args) { 47 new TestCheckCLDR().run(args); 48 } 49 50 static class MyCheckCldr extends org.unicode.cldr.test.CheckCLDR { 51 CheckStatus doTest() { 52 try { 53 throw new IllegalArgumentException("hi"); 54 } catch (Exception e) { 55 return new CheckStatus() 56 .setCause(this) 57 .setMainType(CheckStatus.warningType) 58 .setSubtype(Subtype.abbreviatedDateFieldTooWide) 59 .setMessage("An exception {0}, and a number {1}", e, 60 1.5); 61 } 62 } 63 64 @Override 65 public CheckCLDR handleCheck(String path, String fullPath, 66 String value, Options options, List<CheckStatus> result) { 67 return null; 68 } 69 } 70 71 public void TestExceptions() { 72 CheckStatus status = new MyCheckCldr().doTest(); 73 Exception[] exceptions = status.getExceptionParameters(); 74 assertEquals("Number of exceptions:", exceptions.length, 1); 75 assertEquals("Exception message:", "hi", exceptions[0].getMessage()); 76 logln(Arrays.asList(exceptions[0].getStackTrace()).toString()); 77 logln(status.getMessage()); 78 } 79 80 public static void TestCheckConsistentCasing() { 81 CheckConsistentCasing c = new CheckConsistentCasing( 82 testInfo.getCldrFactory()); 83 Map<String, String> options = new LinkedHashMap<String, String>(); 84 List<CheckStatus> possibleErrors = new ArrayList<CheckStatus>(); 85 final CLDRFile english = testInfo.getEnglish(); 86 c.setCldrFileToCheck(english, options, possibleErrors); 87 for (String path : english) { 88 c.check(path, english.getFullXPath(path), 89 english.getStringValue(path), options, possibleErrors); 90 } 91 } 92 93 /** 94 * Test the "collisionless" error/warning messages. 95 */ 96 97 public static final String INDIVIDUAL_TESTS = ".*(CheckCasing|CheckCurrencies|CheckDates|CheckExemplars|CheckForCopy|CheckForExemplars|CheckMetazones|CheckNumbers)"; 98 static final Factory factory = testInfo.getCldrFactory(); 99 static final CLDRFile english = testInfo.getEnglish(); 100 101 private static final boolean DEBUG = true; 102 103 public void TestPlaceholders() { 104 // verify that every item with {0} has a pattern in pattern 105 // placeholders, 106 // and that every one generates an error in CheckCDLR for patterns when 107 // given "?" 108 // and that every non-pattern doesn't have an error in CheckCLDR for 109 // patterns when given "?" 110 Matcher messagePlaceholder = PatternCache.get("\\{\\d+\\}").matcher(""); 111 PatternPlaceholders patternPlaceholders = PatternPlaceholders 112 .getInstance(); 113 114 CheckCLDR test = CheckCLDR.getCheckAll(factory, ".*"); 115 List<CheckStatus> possibleErrors = new ArrayList<CheckStatus>(); 116 Options options = new Options(); 117 test.setCldrFileToCheck(english, options, possibleErrors); 118 List<CheckStatus> result = new ArrayList<CheckStatus>(); 119 120 PathHeader.Factory pathHeaderFactory = PathHeader.getFactory(english); 121 Set<PathHeader> sorted = new TreeSet<PathHeader>(); 122 for (String path : english.fullIterable()) { 123 sorted.add(pathHeaderFactory.fromPath(path)); 124 } 125 final String testPath = "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"duration-day-future\"]/unitPattern[@count=\"0\"]"; 126 sorted.add(pathHeaderFactory.fromPath(testPath)); 127 128 for (PathHeader pathHeader : sorted) { 129 String path = pathHeader.getOriginalPath(); 130 String value = english.getStringValue(path); 131 if (value == null) { 132 value = "?"; 133 } 134 boolean containsMessagePattern = messagePlaceholder.reset(value) 135 .find(); 136 final Map<String, PlaceholderInfo> placeholderInfo = patternPlaceholders 137 .get(path); 138 final PlaceholderStatus placeholderStatus = patternPlaceholders 139 .getStatus(path); 140 if (containsMessagePattern && placeholderStatus == PlaceholderStatus.DISALLOWED 141 || !containsMessagePattern && placeholderStatus == PlaceholderStatus.REQUIRED) { 142 errln("Value (" + value + ") looks like placeholder = " 143 + containsMessagePattern + ", but placeholder info = " 144 + placeholderStatus + "\t" + path); 145 continue; 146 } else if (placeholderStatus != PlaceholderStatus.DISALLOWED) { 147 if (containsMessagePattern) { 148 Set<String> found = new HashSet<String>(); 149 do { 150 found.add(messagePlaceholder.group()); 151 } while (messagePlaceholder.find()); 152 if (!found.equals(placeholderInfo.keySet())) { 153 // ^//ldml/characterLabels/characterLabelPattern[@type="category_list"] ; {0}=CATEGORY_TYPE family; {1}=REMAINING_ITEMS man, woman, girl 154 if (path.equals("//ldml/characterLabels/characterLabelPattern[@type=\"category-list\"]")) { 155 logKnownIssue("cldrbug:9534", "commenting out characterLabelPattern[@type=\"category-list\"] for now, pending real fix."); 156 } else { 157 errln("Value (" 158 + value 159 + ") has different placeholders than placeholder info (" 160 + placeholderInfo.keySet() + ")\t" + path); 161 } 162 continue; 163 } else { 164 logln("placeholder info = " + placeholderInfo + "\t" 165 + path); 166 } 167 } 168 169 // check that the error messages are right 170 171 test.handleCheck(path, english.getFullXPath(path), "?", 172 options, result); 173 CheckStatus gotIt = null; 174 for (CheckStatus i : result) { 175 if (i.getSubtype() == Subtype.missingPlaceholders) { 176 gotIt = i; 177 } 178 } 179 if (placeholderStatus == PlaceholderStatus.REQUIRED 180 && gotIt == null) { 181 errln("CheckForExemplars SHOULD have detected " 182 + Subtype.missingPlaceholders + " for " 183 + placeholderStatus + " in " + path); 184 if (DEBUG) { 185 test.handleCheck(path, english.getFullXPath(path), "?", 186 options, result); 187 } 188 } else if (placeholderStatus == PlaceholderStatus.OPTIONAL 189 && gotIt != null) { 190 errln("CheckForExemplars should NOT have detected " 191 + Subtype.missingPlaceholders + " for " 192 + placeholderStatus + " in " + path); 193 if (DEBUG) { 194 test.handleCheck(path, english.getFullXPath(path), "?", 195 options, result); 196 } 197 } else { 198 logln("CheckForExemplars found " + result); 199 } 200 } 201 } 202 } 203 204 public void TestFullErrors() { 205 206 CheckCLDR test = CheckCLDR.getCheckAll(factory, INDIVIDUAL_TESTS); 207 CheckCLDR.setDisplayInformation(english); 208 209 final String localeID = "fr"; 210 checkLocale(test, localeID, "?", null); 211 } 212 213 public void TestAllLocales() { 214 215 CheckCLDR test = CheckCLDR.getCheckAll(factory, INDIVIDUAL_TESTS); 216 CheckCLDR.setDisplayInformation(english); 217 Set<String> unique = new HashSet<String>(); 218 219 LanguageTagParser ltp = new LanguageTagParser(); 220 int count = 0; 221 for (String locale : getInclusion() <= 5 ? eightPointLocales : factory.getAvailable()) { 222 if (!ltp.set(locale).getRegion().isEmpty()) { 223 continue; 224 } 225 checkLocale(test, locale, null, unique); 226 ++count; 227 } 228 logln("Count:\t" + count); 229 } 230 231 public void TestA() { 232 233 CheckCLDR test = CheckCLDR.getCheckAll(factory, INDIVIDUAL_TESTS); 234 CheckCLDR.setDisplayInformation(english); 235 Set<String> unique = new HashSet<String>(); 236 237 checkLocale(test, "ko", null, unique); 238 } 239 240 public void checkLocale(CheckCLDR test, String localeID, String dummyValue, 241 Set<String> unique) { 242 checkLocale(test, testInfo.getCLDRFile(localeID, false), dummyValue, unique); 243 } 244 245 public void checkLocale(CheckCLDR test, CLDRFile nativeFile, 246 String dummyValue, Set<String> unique) { 247 String localeID = nativeFile.getLocaleID(); 248 List<CheckStatus> possibleErrors = new ArrayList<CheckStatus>(); 249 CheckCLDR.Options options = new CheckCLDR.Options(); 250 test.setCldrFileToCheck(nativeFile, options, possibleErrors); 251 List<CheckStatus> result = new ArrayList<CheckStatus>(); 252 253 CLDRFile patched = nativeFile; // new CLDRFile(override); 254 PathHeader.Factory pathHeaderFactory = PathHeader.getFactory(english); 255 Set<PathHeader> sorted = new TreeSet<PathHeader>(); 256 for (String path : patched) { 257 final PathHeader pathHeader = pathHeaderFactory.fromPath(path); 258 if (pathHeader != null) { 259 sorted.add(pathHeader); 260 } 261 } 262 263 logln("Checking: " + localeID); 264 UnicodeSet missingCurrencyExemplars = new UnicodeSet(); 265 UnicodeSet missingExemplars = new UnicodeSet(); 266 267 for (PathHeader pathHeader : sorted) { 268 String path = pathHeader.getOriginalPath(); 269 // override.overridePath = path; 270 final String resolvedValue = dummyValue == null ? patched 271 .getStringValue(path) : dummyValue; 272 test.handleCheck(path, patched.getFullXPath(path), resolvedValue, 273 options, result); 274 if (result.size() != 0) { 275 for (CheckStatus item : result) { 276 addExemplars(item, missingCurrencyExemplars, 277 missingExemplars); 278 final String mainMessage = StringId.getId(path) + "\t" 279 + pathHeader + "\t" + english.getStringValue(path) 280 + "\t" + item.getType() + "\t" + item.getSubtype(); 281 if (unique != null) { 282 if (unique.contains(mainMessage)) { 283 continue; 284 } else { 285 unique.add(mainMessage); 286 } 287 } 288 logln(localeID + "\t" + mainMessage + "\t" + resolvedValue 289 + "\t" + item.getMessage() + "\t" 290 + pathHeader.getOriginalPath()); 291 } 292 } 293 } 294 if (missingCurrencyExemplars.size() != 0) { 295 logln(localeID + "\tMissing Exemplars (Currency):\t" 296 + missingCurrencyExemplars.toPattern(false)); 297 } 298 if (missingExemplars.size() != 0) { 299 logln(localeID + "\tMissing Exemplars:\t" 300 + missingExemplars.toPattern(false)); 301 } 302 } 303 304 void addExemplars(CheckStatus status, UnicodeSet missingCurrencyExemplars, 305 UnicodeSet missingExemplars) { 306 Object[] parameters = status.getParameters(); 307 if (parameters != null) { 308 if (parameters.length >= 1 309 && status.getCause().getClass() == CheckForExemplars.class) { 310 try { 311 UnicodeSet set = new UnicodeSet(parameters[0].toString()); 312 if (status.getMessage().contains("currency")) { 313 missingCurrencyExemplars.addAll(set); 314 } else { 315 missingExemplars.addAll(set); 316 } 317 } catch (RuntimeException e) { 318 } // skip if not parseable as set 319 } 320 } 321 } 322 323 public void TestCheckNames() { 324 CheckCLDR c = new CheckNames(); 325 Map<String, String> options = new LinkedHashMap<String, String>(); 326 List<CheckStatus> possibleErrors = new ArrayList<CheckStatus>(); 327 final CLDRFile english = testInfo.getEnglish(); 328 c.setCldrFileToCheck(english, options, possibleErrors); 329 String xpath = "//ldml/localeDisplayNames/languages/language[@type=\"mga\"]"; 330 c.check(xpath, xpath, "Middle Irish (900-1200) ", options, 331 possibleErrors); 332 assertEquals("There should be an error", 1, possibleErrors.size()); 333 334 possibleErrors.clear(); 335 xpath = "//ldml/localeDisplayNames/currencies/currency[@type=\"afa\"]/name"; 336 c.check(xpath, xpath, "Afghan Afghani (1927-2002)", options, 337 possibleErrors); 338 assertEquals("Currencies are allowed to have dates", 0, 339 possibleErrors.size()); 340 } 341 342 public void TestCheckNew() { 343 String path = "//ldml/dates/timeZoneNames/zone[@type=\"Europe/Dublin\"]/long/daylight"; 344 CheckCLDR c = new CheckNew(testInfo.getCldrFactory()); 345 List<CheckStatus> result = new ArrayList<CheckStatus>(); 346 Map<String, String> options = new HashMap<String, String>(); 347 c.setCldrFileToCheck(testInfo.getCLDRFile("fr", true), 348 options, result); 349 c.check(path, path, "foobar", options, result); 350 for (CheckStatus status : result) { 351 if (status.getSubtype() != Subtype.modifiedEnglishValue) { 352 continue; 353 } 354 assertEquals( 355 null, 356 "The English value for this field changed from Irish Summer Time to Irish Standard Time, but the corresponding value for your locale didn't change.", 357 status.getMessage()); 358 return; 359 } 360 errln("No failure message."); 361 } 362 363 public void TestCheckDates() { 364 CheckCLDR.setDisplayInformation(testInfo.getEnglish()); // just in case 365 String prefix = "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dayPeriods/dayPeriodContext[@type=\""; 366 String infix = "\"]/dayPeriodWidth[@type=\"wide\"]/dayPeriod[@type=\""; 367 String suffix = "\"]"; 368 369 TestFactory testFactory = new TestFactory(); 370 371 List<CheckStatus> result = new ArrayList<CheckStatus>(); 372 Options options = new Options(); 373 final String collidingValue = "foobar"; 374 375 // Selection has stricter collision rules, because is is used to select different messages. 376 // So two types with the same localization do collide unless they have exactly the same rules. 377 378 Object[][] tests = { 379 { "en" }, // set locale 380 381 // nothing collides with itself 382 { Type.format, DayPeriod.night1, Type.format, DayPeriod.night1, Subtype.none }, 383 { Type.format, DayPeriod.morning1, Type.format, DayPeriod.morning1, Subtype.none }, 384 { Type.format, DayPeriod.afternoon1, Type.format, DayPeriod.afternoon1, Subtype.none }, 385 { Type.format, DayPeriod.evening1, Type.format, DayPeriod.evening1, Subtype.none }, 386 387 { Type.format, DayPeriod.am, Type.format, DayPeriod.am, Subtype.none }, 388 { Type.format, DayPeriod.pm, Type.format, DayPeriod.pm, Subtype.none }, 389 { Type.format, DayPeriod.noon, Type.format, DayPeriod.noon, Subtype.none }, 390 { Type.format, DayPeriod.midnight, Type.format, DayPeriod.midnight, Subtype.none }, 391 392 { Type.selection, DayPeriod.night1, Type.selection, DayPeriod.night1, Subtype.none }, 393 { Type.selection, DayPeriod.morning1, Type.selection, DayPeriod.morning1, Subtype.none }, 394 { Type.selection, DayPeriod.afternoon1, Type.selection, DayPeriod.afternoon1, Subtype.none }, 395 { Type.selection, DayPeriod.evening1, Type.selection, DayPeriod.evening1, Subtype.none }, 396 397 { Type.selection, DayPeriod.am, Type.selection, DayPeriod.am, Subtype.none }, 398 { Type.selection, DayPeriod.pm, Type.selection, DayPeriod.pm, Subtype.none }, 399 { Type.selection, DayPeriod.noon, Type.selection, DayPeriod.noon, Subtype.none }, 400 { Type.selection, DayPeriod.midnight, Type.selection, DayPeriod.midnight, Subtype.none }, 401 402 // fixed classes always collide 403 { Type.format, DayPeriod.am, Type.format, DayPeriod.pm, Subtype.dateSymbolCollision }, 404 { Type.format, DayPeriod.am, Type.format, DayPeriod.noon, Subtype.dateSymbolCollision }, 405 { Type.format, DayPeriod.am, Type.format, DayPeriod.midnight, Subtype.dateSymbolCollision }, 406 { Type.format, DayPeriod.pm, Type.format, DayPeriod.noon, Subtype.dateSymbolCollision }, 407 { Type.format, DayPeriod.pm, Type.format, DayPeriod.midnight, Subtype.dateSymbolCollision }, 408 { Type.format, DayPeriod.noon, Type.format, DayPeriod.midnight, Subtype.dateSymbolCollision }, 409 410 { Type.selection, DayPeriod.am, Type.selection, DayPeriod.pm, Subtype.dateSymbolCollision }, 411 { Type.selection, DayPeriod.am, Type.selection, DayPeriod.noon, Subtype.dateSymbolCollision }, 412 { Type.selection, DayPeriod.am, Type.selection, DayPeriod.midnight, Subtype.dateSymbolCollision }, 413 { Type.selection, DayPeriod.pm, Type.selection, DayPeriod.noon, Subtype.dateSymbolCollision }, 414 { Type.selection, DayPeriod.pm, Type.selection, DayPeriod.midnight, Subtype.dateSymbolCollision }, 415 { Type.selection, DayPeriod.noon, Type.selection, DayPeriod.midnight, Subtype.dateSymbolCollision }, 416 417 // 00-06 night1 418 // 06-12 morning1 419 // 12-18 afternoon1 420 // 18-21 evening1 421 // 21-24 night1 422 // 423 // So for a 12hour time, we have: 424 // 425 // 12 1 2 3 4 5 6 7 8 9 10 11 426 // n n n n n n m m m m m m 427 // a a a a a a e e e n n n 428 429 // Formatting has looser collision rules, because it is always paired with a time. 430 // That is, it is not a problem if two items collide, 431 // if it doesn't cause a collision when paired with a time. 432 // But if 11:00 has the same format (eg 11 X) as 23:00, there IS a collision. 433 // So we see if there is an overlap mod 12. 434 435 { Type.format, DayPeriod.night1, Type.format, DayPeriod.morning1, Subtype.dateSymbolCollision }, 436 { Type.format, DayPeriod.night1, Type.format, DayPeriod.afternoon1, Subtype.dateSymbolCollision }, 437 { Type.format, DayPeriod.night1, Type.format, DayPeriod.evening1, Subtype.none }, 438 439 { Type.format, DayPeriod.morning1, Type.format, DayPeriod.afternoon1, Subtype.none }, 440 { Type.format, DayPeriod.morning1, Type.format, DayPeriod.evening1, Subtype.dateSymbolCollision }, 441 442 { Type.format, DayPeriod.afternoon1, Type.format, DayPeriod.evening1, Subtype.none }, 443 444 // Selection has stricter collision rules, because is is used to select different messages. 445 // So two types with the same localization do collide unless they have exactly the same rules. 446 // We use chr to test the "unless they have exactly the same rules" below. 447 448 { Type.selection, DayPeriod.morning1, Type.selection, DayPeriod.night1, Subtype.dateSymbolCollision }, 449 { Type.selection, DayPeriod.morning1, Type.selection, DayPeriod.afternoon1, Subtype.dateSymbolCollision }, 450 451 { Type.selection, DayPeriod.morning1, Type.selection, DayPeriod.am, Subtype.none }, // morning1 and am is allowable 452 { Type.selection, DayPeriod.morning1, Type.selection, DayPeriod.pm, Subtype.dateSymbolCollision }, 453 454 { "fr" }, 455 456 // nothing collides with itself 457 { Type.format, DayPeriod.night1, Type.format, DayPeriod.night1, Subtype.none }, 458 { Type.format, DayPeriod.morning1, Type.format, DayPeriod.morning1, Subtype.none }, 459 { Type.format, DayPeriod.afternoon1, Type.format, DayPeriod.afternoon1, Subtype.none }, 460 { Type.format, DayPeriod.evening1, Type.format, DayPeriod.evening1, Subtype.none }, 461 462 // French has different rules 463 // 00-04 night1 464 // 04-12 morning1 465 // 12-18 afternoon1 466 // 18-00 evening1 467 // 468 // So for a 12hour time, we have: 469 // 470 // 12 1 2 3 4 5 6 7 8 9 10 11 471 // n n n n m m m m m m m m 472 // a a a a a a e e e e e e 473 474 { Type.format, DayPeriod.night1, Type.format, DayPeriod.morning1, Subtype.none }, 475 { Type.format, DayPeriod.night1, Type.format, DayPeriod.afternoon1, Subtype.dateSymbolCollision }, 476 { Type.format, DayPeriod.night1, Type.format, DayPeriod.evening1, Subtype.none }, 477 478 { Type.format, DayPeriod.morning1, Type.format, DayPeriod.afternoon1, Subtype.dateSymbolCollision }, 479 { Type.format, DayPeriod.morning1, Type.format, DayPeriod.evening1, Subtype.dateSymbolCollision }, 480 481 { Type.format, DayPeriod.afternoon1, Type.format, DayPeriod.evening1, Subtype.none }, 482 483 { "chr" }, 484 // Chr lets use test that same rules don't collide in selection 485 // <dayPeriodRule type="morning1" from="0:00" before="12:00" /> 486 // <dayPeriodRule type="noon" at="12:00" /> 487 // <dayPeriodRule type="afternoon1" after="12:00" before="24:00" /> 488 { Type.selection, DayPeriod.morning1, Type.selection, DayPeriod.am, Subtype.none }, 489 { Type.selection, DayPeriod.afternoon1, Type.selection, DayPeriod.pm, Subtype.none }, 490 }; 491 CLDRFile testFile = null; 492 for (Object[] test : tests) { 493 // set locale 494 if (test.length == 1) { 495 if (testFile != null) { 496 logln(""); 497 } 498 testFile = new CLDRFile(new SimpleXMLSource((String) test[0])); 499 testFactory.addFile(testFile); 500 continue; 501 } 502 final DayPeriodInfo.Type type1 = (Type) test[0]; 503 final DayPeriodInfo.DayPeriod period1 = (DayPeriod) test[1]; 504 final DayPeriodInfo.Type type2 = (Type) test[2]; 505 final DayPeriodInfo.DayPeriod period2 = (DayPeriod) test[3]; 506 final Subtype expectedSubtype = (Subtype) test[4]; 507 508 final String path1 = prefix + type1.pathValue + infix + period1 + suffix; 509 final String path2 = prefix + type2.pathValue + infix + period2 + suffix; 510 511 testFile.add(path1, collidingValue); 512 testFile.add(path2, collidingValue); 513 514 CheckCLDR c = new CheckDates(testFactory); 515 c.setCldrFileToCheck(testFile, options, result); 516 517 result.clear(); 518 c.check(path1, path1, collidingValue, options, result); 519 Subtype actualSubtype = Subtype.none; 520 String message = null; 521 for (CheckStatus status : result) { 522 actualSubtype = status.getSubtype(); 523 message = status.getMessage(); 524 break; 525 } 526 assertEquals(testFile.getLocaleID() + " " + type1 + "/" + period1 + " vs " + type2 + "/" + period2 527 + (message == null ? "" : " [" + message + "]"), expectedSubtype, actualSubtype); 528 529 testFile.remove(path1); 530 testFile.remove(path2); 531 } 532 } 533 } 534