1 /* 2 * Copyright (C) 2011 The Libphonenumber Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.i18n.phonenumbers; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertNull; 21 import static org.junit.Assert.assertTrue; 22 import static org.junit.Assert.fail; 23 24 import com.google.i18n.phonenumbers.BuildMetadataCppFromXml.Options; 25 import com.google.i18n.phonenumbers.BuildMetadataCppFromXml.Variant; 26 import com.google.i18n.phonenumbers.CppMetadataGenerator.Type; 27 28 import org.junit.Test; 29 30 import java.io.ByteArrayOutputStream; 31 import java.io.File; 32 import java.io.OutputStream; 33 import java.nio.charset.Charset; 34 35 /** 36 * Tests the BuildMetadataCppFromXml implementation to make sure it parses command line options and 37 * generates code correctly. 38 */ 39 public class BuildMetadataCppFromXmlTest { 40 41 // Various repeated test strings and data. 42 private static final String IGNORED = "IGNORED"; 43 private static final String OUTPUT_DIR = "output/dir"; 44 private static final String INPUT_PATH_XML = "input/path.xml"; 45 private static final byte[] TEST_DATA = 46 new byte[] { (byte) 0xCA, (byte) 0xFE, (byte) 0xBA, (byte) 0xBE }; 47 private static final String CPP_TEST_DATA = "0xCA, 0xFE, 0xBA, 0xBE"; 48 49 @Test parseVariant()50 public void parseVariant() { 51 assertNull(Variant.parse("xxx")); 52 assertEquals(Variant.FULL, Variant.parse(null)); 53 assertEquals(Variant.FULL, Variant.parse("")); 54 assertEquals(Variant.LITE, Variant.parse("lite")); 55 assertEquals(Variant.TEST, Variant.parse("test")); 56 assertEquals(Variant.LITE, Variant.parse("LITE")); 57 assertEquals(Variant.TEST, Variant.parse("Test")); 58 } 59 60 @Test parseBadOptions()61 public void parseBadOptions() { 62 try { 63 BuildMetadataCppFromXml.Options.parse("MyCommand", new String[] { IGNORED }); 64 fail("Expected exception not thrown"); 65 } catch (IllegalArgumentException e) { 66 assertTrue(e.getMessage().contains("MyCommand")); 67 } 68 } 69 70 @Test parseGoodOptions()71 public void parseGoodOptions() { 72 Options opt = BuildMetadataCppFromXml.Options.parse("MyCommand", 73 new String[] { IGNORED, INPUT_PATH_XML, OUTPUT_DIR, "test_alternate_format" }); 74 assertEquals(Type.ALTERNATE_FORMAT, opt.getType()); 75 assertEquals(Variant.TEST, opt.getVariant()); 76 assertEquals(INPUT_PATH_XML, opt.getInputFilePath()); 77 assertEquals(OUTPUT_DIR, opt.getOutputDir()); 78 } 79 80 @Test generateMetadata()81 public void generateMetadata() { 82 String[] args = new String[] { 83 IGNORED, INPUT_PATH_XML, OUTPUT_DIR, "metadata" }; 84 // Most of the useful asserts are done in the mock class. 85 MockedCommand command = new MockedCommand( 86 INPUT_PATH_XML, false, OUTPUT_DIR, Type.METADATA, Variant.FULL); 87 command.setArgs(args); 88 command.start(); 89 // Sanity check the captured data (asserting implicitly that the mocked methods were called). 90 String headerString = command.capturedHeaderFile(); 91 assertTrue(headerString.contains("const void* metadata_get()")); 92 assertTrue(headerString.contains("int metadata_size()")); 93 String sourceString = command.capturedSourceFile(); 94 assertTrue(sourceString.contains("const void* metadata_get()")); 95 assertTrue(sourceString.contains("int metadata_size()")); 96 assertTrue(sourceString.contains(CPP_TEST_DATA)); 97 } 98 99 @Test generateLiteMetadata()100 public void generateLiteMetadata() { 101 String[] args = new String[] { 102 IGNORED, INPUT_PATH_XML, OUTPUT_DIR, "lite_metadata" }; 103 // Most of the useful asserts are done in the mock class. 104 MockedCommand command = new MockedCommand( 105 INPUT_PATH_XML, true, OUTPUT_DIR, Type.METADATA, Variant.LITE); 106 command.setArgs(args); 107 command.start(); 108 // Sanity check the captured data (asserting implicitly that the mocked methods were called). 109 String headerString = command.capturedHeaderFile(); 110 assertTrue(headerString.contains("const void* metadata_get()")); 111 assertTrue(headerString.contains("int metadata_size()")); 112 String sourceString = command.capturedSourceFile(); 113 assertTrue(sourceString.contains("const void* metadata_get()")); 114 assertTrue(sourceString.contains("int metadata_size()")); 115 assertTrue(sourceString.contains(CPP_TEST_DATA)); 116 } 117 118 @Test generateAlternateFormat()119 public void generateAlternateFormat() { 120 String[] args = new String[] { 121 IGNORED, INPUT_PATH_XML, OUTPUT_DIR, "alternate_format" }; 122 // Most of the useful asserts are done in the mock class. 123 MockedCommand command = new MockedCommand( 124 INPUT_PATH_XML, false, OUTPUT_DIR, Type.ALTERNATE_FORMAT, Variant.FULL); 125 command.setArgs(args); 126 command.start(); 127 // Sanity check the captured data (asserting implicitly that the mocked methods were called). 128 String headerString = command.capturedHeaderFile(); 129 assertTrue(headerString.contains("const void* alternate_format_get()")); 130 assertTrue(headerString.contains("int alternate_format_size()")); 131 String sourceString = command.capturedSourceFile(); 132 assertTrue(sourceString.contains("const void* alternate_format_get()")); 133 assertTrue(sourceString.contains("int alternate_format_size()")); 134 assertTrue(sourceString.contains(CPP_TEST_DATA)); 135 } 136 137 /** 138 * Manually mocked subclass of BuildMetadataCppFromXml which overrides all file related behavior 139 * while asserting the validity of any parameters passed to the mocked methods. After starting 140 * this command, the captured header and source file contents can be retrieved for testing. 141 */ 142 static class MockedCommand extends BuildMetadataCppFromXml { 143 private static final Charset UTF_8 = Charset.forName("UTF-8"); 144 private final String expectedInputFilePath; 145 private final boolean expectedLiteMetadata; 146 private final String expectedOutputDirPath; 147 private final Type expectedType; 148 private final Variant expectedVariant; 149 private final ByteArrayOutputStream headerOut = new ByteArrayOutputStream(); 150 private final ByteArrayOutputStream sourceOut = new ByteArrayOutputStream(); 151 MockedCommand(String expectedInputFilePath, boolean expectedLiteMetadata, String expectedOutputDirPath, Type expectedType, Variant expectedVariant)152 public MockedCommand(String expectedInputFilePath, boolean expectedLiteMetadata, 153 String expectedOutputDirPath, Type expectedType, Variant expectedVariant) { 154 155 this.expectedInputFilePath = expectedInputFilePath; 156 this.expectedLiteMetadata = expectedLiteMetadata; 157 this.expectedOutputDirPath = expectedOutputDirPath; 158 this.expectedType = expectedType; 159 this.expectedVariant = expectedVariant; 160 } writePhoneMetadataCollection( String inputFilePath, boolean liteMetadata, OutputStream out)161 @Override void writePhoneMetadataCollection( 162 String inputFilePath, boolean liteMetadata, OutputStream out) throws Exception { 163 assertEquals(expectedInputFilePath, inputFilePath); 164 assertEquals(expectedLiteMetadata, liteMetadata); 165 out.write(TEST_DATA, 0, TEST_DATA.length); 166 } openHeaderStream(File dir, Type type)167 @Override OutputStream openHeaderStream(File dir, Type type) { 168 assertEquals(expectedOutputDirPath, dir.getPath()); 169 assertEquals(expectedType, type); 170 return headerOut; 171 } openSourceStream(File dir, Type type, Variant variant)172 @Override OutputStream openSourceStream(File dir, Type type, Variant variant) { 173 assertEquals(expectedOutputDirPath, dir.getPath()); 174 assertEquals(expectedType, type); 175 assertEquals(expectedVariant, variant); 176 return sourceOut; 177 } capturedHeaderFile()178 String capturedHeaderFile() { 179 return new String(headerOut.toByteArray(), UTF_8); 180 } capturedSourceFile()181 String capturedSourceFile() { 182 return new String(sourceOut.toByteArray(), UTF_8); 183 } 184 } 185 } 186