1 package org.unicode.cldr.unittest; 2 3 import java.io.ByteArrayInputStream; 4 import java.io.File; 5 import java.io.InputStream; 6 import java.io.PrintWriter; 7 import java.io.StringWriter; 8 import java.nio.charset.StandardCharsets; 9 import java.util.Arrays; 10 import java.util.List; 11 import java.util.Map; 12 import java.util.Set; 13 import java.util.TreeSet; 14 import java.util.function.Predicate; 15 16 import org.unicode.cldr.util.CLDRConfig; 17 import org.unicode.cldr.util.CLDRFile; 18 import org.unicode.cldr.util.CLDRFile.DraftStatus; 19 import org.unicode.cldr.util.CLDRPaths; 20 import org.unicode.cldr.util.Factory; 21 import org.unicode.cldr.util.SimpleFactory; 22 import org.unicode.cldr.util.SimpleXMLSource; 23 import org.unicode.cldr.util.SupplementalDataInfo; 24 25 import com.google.common.base.Objects; 26 import com.google.common.collect.ImmutableMap; 27 28 public class TestCldrFactory extends TestFmwkPlus { 29 private static final boolean DEBUG = false; 30 31 static CLDRConfig testInfo = CLDRConfig.getInstance(); 32 static SupplementalDataInfo sdi = testInfo.getSupplementalDataInfo(); 33 main(String[] args)34 public static void main(String[] args) { 35 new TestCldrFactory().run(args); 36 } 37 testDirectories()38 public void testDirectories() { 39 File[] paths = { 40 new File(CLDRPaths.MAIN_DIRECTORY), 41 new File(CLDRPaths.ANNOTATIONS_DIRECTORY), 42 new File(CLDRPaths.SUPPLEMENTAL_DIRECTORY) 43 }; 44 Factory factory = SimpleFactory.make(paths, ".*"); 45 List<File> enExpected = Arrays.asList(new File(CLDRPaths.MAIN_DIRECTORY), new File(CLDRPaths.ANNOTATIONS_DIRECTORY)); 46 47 File[] dirs = factory.getSourceDirectories(); 48 assertEquals("", Arrays.asList(paths), Arrays.asList(dirs)); 49 50 List<File> enDirs = factory.getSourceDirectoriesForLocale("en"); 51 assertEquals("", enExpected, enDirs); 52 53 // Make sure old method works 54 File enDir = factory.getSourceDirectoryForLocale("en"); 55 assertEquals("", new File(CLDRPaths.MAIN_DIRECTORY), enDir); 56 } 57 testMerge()58 public void testMerge() { 59 CLDRFile enMain = testInfo.getCldrFactory().make("en", false); 60 assertEquals("no annotations", Status.noAnnotations, checkAnnotations(enMain)); 61 62 Factory factoryAnnotations = SimpleFactory.make(CLDRPaths.ANNOTATIONS_DIRECTORY, ".*"); 63 CLDRFile enAnnotations = factoryAnnotations.make("en", false); 64 assertEquals("annotations only", Status.onlyAnnotations, checkAnnotations(enAnnotations)); 65 66 File[] paths = { new File(CLDRPaths.MAIN_DIRECTORY), new File(CLDRPaths.ANNOTATIONS_DIRECTORY) }; 67 Factory factoryDouble = SimpleFactory.make(paths, ".*"); 68 69 CLDRFile enDouble = factoryDouble.make("en", false); 70 assertEquals("annotations only", Status.mixed, checkAnnotations(enDouble)); 71 72 assertEquals("no annotations", Status.noAnnotations, checkAnnotations(enMain)); 73 assertEquals("annotations only", Status.onlyAnnotations, checkAnnotations(enAnnotations)); 74 assertEquals("annotations only", Status.mixed, checkAnnotations(enDouble)); 75 76 assertEquals("en subset of enDouble", null, getUncontainedPath(enMain, enDouble)); 77 assertEquals("enAnnotations subset of enDouble", null, getUncontainedPath(enAnnotations, enDouble)); 78 } 79 80 enum Status { 81 none, onlyAnnotations, noAnnotations, mixed 82 } 83 checkAnnotations(CLDRFile cldrFile)84 private Status checkAnnotations(CLDRFile cldrFile) { 85 Status status = Status.none; 86 for (String xpath : cldrFile) { 87 if (xpath.startsWith("//ldml/identity")) continue; 88 boolean isAnnotation = xpath.startsWith("//ldml/annotation"); 89 if (isAnnotation) { 90 switch (status) { 91 case none: 92 status = Status.onlyAnnotations; 93 break; 94 case noAnnotations: 95 return Status.mixed; 96 } 97 } else { 98 switch (status) { 99 case none: 100 status = Status.noAnnotations; 101 break; 102 case onlyAnnotations: 103 return Status.mixed; 104 } 105 } 106 } 107 return status; 108 } 109 110 /** 111 * Returns first string that has a different value in superset than in subset. 112 * @param subset 113 * @param superset 114 * @return 115 */ getUncontainedPath(CLDRFile subset, CLDRFile superset)116 private String getUncontainedPath(CLDRFile subset, CLDRFile superset) { 117 int debugCount = 0; 118 for (String xpath : subset) { 119 if (++debugCount < 100) { 120 logln(debugCount + "\t" + xpath); 121 } 122 String subValue = subset.getStringValue(xpath); 123 String superValue = superset.getStringValue(xpath); 124 if (!Objects.equal(subValue, superValue)) { 125 return xpath; 126 } 127 } 128 return null; 129 } 130 131 /** 132 * Returns first string that has a different value in a than in b. 133 * @param subset 134 * @param superset 135 * @return 136 */ differentPathValue(CLDRFile a, CLDRFile b)137 private String differentPathValue(CLDRFile a, CLDRFile b) { 138 int debugCount = 0; 139 Set<String> paths = new TreeSet<>(); 140 a.forEach(paths::add); 141 b.forEach(paths::add); 142 for (String xpath : paths) { 143 if (++debugCount < 100) { 144 logln(debugCount + "\t" + xpath); 145 } 146 String aValue = a.getStringValue(xpath); 147 String bValue = b.getStringValue(xpath); 148 if (!Objects.equal(aValue, bValue)) { 149 return xpath; 150 } 151 } 152 return null; 153 } 154 testWrite()155 public void testWrite() { 156 Predicate<String> isAnnotations = x -> x.startsWith("//ldml/annotations"); 157 Map<String, ?> skipAnnotations = ImmutableMap.of("SKIP_PATH", isAnnotations); 158 Map<String, ?> keepAnnotations = ImmutableMap.of("SKIP_PATH", isAnnotations.negate()); 159 160 CLDRFile enMain = testInfo.getCldrFactory().make("en", false); 161 162 Factory factoryAnnotations = SimpleFactory.make(CLDRPaths.ANNOTATIONS_DIRECTORY, ".*"); 163 CLDRFile enAnnotations = factoryAnnotations.make("en", false); 164 165 File[] paths = { new File(CLDRPaths.MAIN_DIRECTORY), new File(CLDRPaths.ANNOTATIONS_DIRECTORY) }; 166 Factory factoryDouble = SimpleFactory.make(paths, ".*"); 167 CLDRFile enDouble = factoryDouble.make("en", false); 168 169 String temp = cldrFileToString(enDouble, skipAnnotations); 170 if (DEBUG) { 171 System.out.println("Without Annotations\t"); 172 System.out.println(temp); 173 } 174 CLDRFile enDoubleWithoutAnnotations = cldrFileFromString(temp); 175 assertEquals("enMain == enDoubleWithoutAnnotations", null, differentPathValue(enMain, enDoubleWithoutAnnotations)); 176 177 temp = cldrFileToString(enDouble, keepAnnotations); 178 if (DEBUG) { 179 System.out.println("With Annotations\t"); 180 System.out.println(temp); 181 } 182 CLDRFile enDoubleWithAnnotations = cldrFileFromString(temp); 183 assertEquals("enAnnotations == enDoubleWithAnnotations", null, differentPathValue(enAnnotations, enDoubleWithAnnotations)); 184 } 185 cldrFileFromString(String string)186 private CLDRFile cldrFileFromString(String string) { 187 byte[] b = string.getBytes(StandardCharsets.UTF_8); 188 InputStream fis = new ByteArrayInputStream(b); 189 CLDRFile filteredCldrFile = new CLDRFile(new SimpleXMLSource("enx")); 190 filteredCldrFile.loadFromInputStream("enx", "enx", fis, DraftStatus.unconfirmed); 191 return filteredCldrFile; 192 } 193 cldrFileToString(CLDRFile sourceCldrFile, Map<String, ?> options)194 private String cldrFileToString(CLDRFile sourceCldrFile, Map<String, ?> options) { 195 StringWriter stringWriter = new StringWriter(); 196 PrintWriter pw = new PrintWriter(stringWriter); 197 sourceCldrFile.write(pw, options); 198 pw.flush(); 199 return stringWriter.toString(); 200 } 201 } 202