TOOLS: Update GenerateAreaCodeData and add some unit tests for it.
authorphilip.liard@gmail.com <philip.liard@gmail.com@ee073f10-1060-11df-b6a4-87a95322a99c>
Mon, 4 Jul 2011 14:19:57 +0000 (14:19 +0000)
committerphilip.liard@gmail.com <philip.liard@gmail.com@ee073f10-1060-11df-b6a4-87a95322a99c>
Mon, 4 Jul 2011 14:19:57 +0000 (14:19 +0000)
git-svn-id: http://libphonenumber.googlecode.com/svn/trunk@285 ee073f10-1060-11df-b6a4-87a95322a99c

tools/java/java-build/pom.xml
tools/java/java-build/src/com/google/i18n/phonenumbers/tools/GenerateAreaCodeData.java
tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar
tools/java/java-build/test/com/google/i18n/phonenumbers/tools/GenerateAreaCodeDataTest.java [new file with mode: 0644]

index 1e35591..571256a 100644 (file)
     text to binary format.
   </description>
 
+  <properties>
+    <phonenumberutil.resources.dir>
+      ${project.dir}/../../../../java/src/
+    </phonenumberutil.resources.dir>
+  </properties>
+
   <build>
     <sourceDirectory>src</sourceDirectory>
     <testSourceDirectory>test</testSourceDirectory>
+    <!-- Include the PhoneNumberUtil metadata files. -->
+    <resources>
+      <resource>
+        <directory>${phonenumberutil.resources.dir}</directory>
+      </resource>
+    </resources>
+    <testResources>
+      <testResource>
+        <directory>${phonenumberutil.resources.dir}</directory>
+      </testResource>
+    </testResources>
     <plugins>
       <plugin>
         <version>2.3.2</version>
index 7951f91..96883bf 100644 (file)
@@ -111,31 +111,35 @@ public class GenerateAreaCodeData extends Command {
    *
    * @VisibleForTesting
    */
-  static void convertData(InputStream input, OutputStream output) throws IOException {
+  static void convertData(
+      InputStream input, OutputStream output, int countryCallingCode) throws IOException {
     SortedMap<Integer, String> areaCodeMapTemp = new TreeMap<Integer, String>();
     BufferedReader bufferedReader =
         new BufferedReader(new InputStreamReader(
             new BufferedInputStream(input), Charset.forName("UTF-8")));
-    for (String line; (line = bufferedReader.readLine()) != null; ) {
+    int lineNumber = 1;
+
+    for (String line; (line = bufferedReader.readLine()) != null; lineNumber++) {
       line = line.trim();
       if (line.length() == 0 || line.startsWith("#")) {
         continue;
       }
       int indexOfPipe = line.indexOf('|');
       if (indexOfPipe == -1) {
-        LOGGER.log(Level.WARNING, "Malformatted data: expected '|'");
-        continue;
+        throw new RuntimeException(String.format("line %d: malformatted data, expected '|'",
+                                                 lineNumber));
       }
       String areaCode = line.substring(0, indexOfPipe);
       if (indexOfPipe == line.length() - 1) {
-        LOGGER.log(Level.WARNING, "Missing location for area code " + areaCode);
-        continue;
+        throw new RuntimeException(String.format("line %d: missing location", lineNumber));
       }
       String location = line.substring(indexOfPipe + 1);
-      areaCodeMapTemp.put(Integer.parseInt(areaCode), location);
+      if (areaCodeMapTemp.put(Integer.parseInt(areaCode), location) != null) {
+        throw new RuntimeException(String.format("line %d: duplicated area code", lineNumber));
+      }
     }
     // Build the corresponding area code map and serialize it to the binary format.
-    AreaCodeMap areaCodeMap = new AreaCodeMap();
+    AreaCodeMap areaCodeMap = new AreaCodeMap(countryCallingCode);
     areaCodeMap.readAreaCodeMap(areaCodeMapTemp);
     ObjectOutputStream objectOutputStream = new ObjectOutputStream(output);
     areaCodeMap.writeExternal(objectOutputStream);
@@ -173,15 +177,13 @@ public class GenerateAreaCodeData extends Command {
         String countryCodeFileName = countryCodeFile.getName();
         int indexOfDot = countryCodeFileName.indexOf('.');
         if (indexOfDot == -1) {
-          LOGGER.log(Level.WARNING,
-                     String.format("unexpected file name %s, expected pattern .*\\.txt",
-                                   countryCodeFileName));
-          continue;
+          throw new RuntimeException(
+              String.format("unexpected file name %s, expected pattern .*\\.txt",
+                            countryCodeFileName));
         }
         String countryCode = countryCodeFileName.substring(0, indexOfDot);
         if (!countryCode.matches("\\d+")) {
-          LOGGER.log(Level.WARNING, "ignoring unexpected file " + countryCodeFileName);
-          continue;
+          throw new RuntimeException("ignoring unexpected file " + countryCodeFileName);
         }
         mappings.add(new Pair<File, File>(
             countryCodeFile,
@@ -199,8 +201,8 @@ public class GenerateAreaCodeData extends Command {
    *
    * @VisibleForTesting
    */
-  static void addConfigurationMapping(SortedMap<Integer, Set<String>> availableDataFiles,
-                                      File outputAreaCodeMappingsFile) {
+  static int addConfigurationMapping(SortedMap<Integer, Set<String>> availableDataFiles,
+                                     File outputAreaCodeMappingsFile) {
     String outputAreaCodeMappingsFileName = outputAreaCodeMappingsFile.getName();
     int indexOfUnderscore = outputAreaCodeMappingsFileName.indexOf('_');
     int countryCode = Integer.parseInt(
@@ -213,6 +215,7 @@ public class GenerateAreaCodeData extends Command {
       availableDataFiles.put(countryCode, languageSet);
     }
     languageSet.add(language);
+    return countryCode;
   }
 
   /**
@@ -252,8 +255,9 @@ public class GenerateAreaCodeData extends Command {
         File binaryFile = inputOutputMapping.second;
         fileInputStream = new FileInputStream(textFile);
         fileOutputStream = new FileOutputStream(binaryFile);
-        convertData(fileInputStream, fileOutputStream);
-        addConfigurationMapping(availableDataFiles, inputOutputMapping.second);
+        int countryCallingCode =
+            addConfigurationMapping(availableDataFiles, inputOutputMapping.second);
+        convertData(fileInputStream, fileOutputStream, countryCallingCode);
       } catch (IOException e) {
         LOGGER.log(Level.SEVERE, e.getMessage());
         continue;
index 09500ef..1055572 100644 (file)
Binary files a/tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar and b/tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar differ
diff --git a/tools/java/java-build/test/com/google/i18n/phonenumbers/tools/GenerateAreaCodeDataTest.java b/tools/java/java-build/test/com/google/i18n/phonenumbers/tools/GenerateAreaCodeDataTest.java
new file mode 100644 (file)
index 0000000..49d2eec
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.i18n.phonenumbers.tools;
+
+import com.google.i18n.phonenumbers.geocoding.AreaCodeMap;
+import com.google.i18n.phonenumbers.geocoding.MappingFileProvider;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.util.Collections;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+/**
+ * Unittests for GenerateAreaCodeData.java
+ *
+ * @author Philippe Liard
+ */
+public class GenerateAreaCodeDataTest extends TestCase {
+  private static final SortedMap<Integer, Set<String>> AVAILABLE_DATA_FILES;
+  static {
+    SortedMap<Integer, Set<String>> temporaryMap = new TreeMap<Integer, Set<String>>();
+
+    // Languages for US.
+    GenerateAreaCodeData.addConfigurationMapping(temporaryMap, new File("1_en"));
+    GenerateAreaCodeData.addConfigurationMapping(temporaryMap, new File("1_en_US"));
+    GenerateAreaCodeData.addConfigurationMapping(temporaryMap, new File("1_es"));
+
+    // Languages for France.
+    GenerateAreaCodeData.addConfigurationMapping(temporaryMap, new File("33_fr"));
+    GenerateAreaCodeData.addConfigurationMapping(temporaryMap, new File("33_en"));
+
+    // Languages for China.
+    GenerateAreaCodeData.addConfigurationMapping(temporaryMap, new File("86_zh_Hans"));
+
+    AVAILABLE_DATA_FILES = Collections.unmodifiableSortedMap(temporaryMap);
+  }
+
+  public void testAddConfigurationMapping() {
+    assertEquals(3, AVAILABLE_DATA_FILES.size());
+
+    Set<String> languagesForUS = AVAILABLE_DATA_FILES.get(1);
+    assertEquals(3, languagesForUS.size());
+    assertTrue(languagesForUS.contains("en"));
+    assertTrue(languagesForUS.contains("en_US"));
+    assertTrue(languagesForUS.contains("es"));
+
+    Set<String> languagesForFR = AVAILABLE_DATA_FILES.get(33);
+    assertEquals(2, languagesForFR.size());
+    assertTrue(languagesForFR.contains("fr"));
+    assertTrue(languagesForFR.contains("en"));
+
+    Set<String> languagesForCN = AVAILABLE_DATA_FILES.get(86);
+    assertEquals(1, languagesForCN.size());
+    assertTrue(languagesForCN.contains("zh_Hans"));
+  }
+
+  public void testOutputBinaryConfiguration() throws IOException {
+    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+    GenerateAreaCodeData.outputBinaryConfiguration(AVAILABLE_DATA_FILES, byteArrayOutputStream);
+    MappingFileProvider mappingFileProvider = new MappingFileProvider();
+    mappingFileProvider.readExternal(
+        new ObjectInputStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray())));
+    assertEquals("1|en,en_US,es,\n33|en,fr,\n86|zh_Hans,\n", mappingFileProvider.toString());
+  }
+
+  private static String convertData(String input, int countryCallingCode) throws IOException {
+    ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(input.getBytes());
+    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+
+    GenerateAreaCodeData.convertData(
+        byteArrayInputStream, byteArrayOutputStream, countryCallingCode);
+    // The byte array output stream now contains the corresponding serialized area code map. Try
+    // to deserialize it and compare it with the initial input.
+    AreaCodeMap areaCodeMap = new AreaCodeMap(countryCallingCode);
+    areaCodeMap.readExternal(
+        new ObjectInputStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray())));
+
+    return areaCodeMap.toString();
+  }
+
+  public void testConvertData() throws IOException {
+    String input = "331|Paris\n334|Marseilles\n";
+
+    String dataAfterDeserialization = convertData(input, 33);
+    assertEquals(input, dataAfterDeserialization);
+    // Make sure convertData() ignores comments.
+    dataAfterDeserialization = convertData("  # Comment.\n" + input, 33);
+    assertEquals(input, dataAfterDeserialization);
+    // Make sure convertData() ignores blank lines.
+    dataAfterDeserialization = convertData("\n" + input, 33);
+    assertEquals(input, dataAfterDeserialization);
+    // Make sure convertData() ignores trailing white spaces.
+    dataAfterDeserialization = convertData(" \n" + input, 33);
+    assertEquals(input, dataAfterDeserialization);
+  }
+
+  public void testConvertDataThrowsExceptionWithMalformattedData() throws IOException {
+    String input = "331";
+
+    try {
+      convertData(input, 33);
+      fail();
+    } catch (RuntimeException e) {
+      // Expected.
+    }
+  }
+
+  public void testConvertDataThrowsExceptionWithMissingLocation() throws IOException {
+    String input = "331|";
+
+    try {
+      convertData(input, 33);
+      fail();
+    } catch (RuntimeException e) {
+      // Expected.
+    }
+  }
+
+  public void testConvertDataThrowsExceptionWithDuplicatedAreaCodes() throws IOException {
+    String input = "331|Paris\n331|Marseilles\n";
+
+    try {
+      convertData(input, 33);
+      fail();
+    } catch (RuntimeException e) {
+      // Expected.
+    }
+  }
+}