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