| /* |
| * Copyright (C) 2011 The Libphonenumber Authors |
| * |
| * 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; |
| |
| import com.google.i18n.phonenumbers.Phonemetadata.NumberFormat; |
| import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata; |
| import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection; |
| import com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc; |
| import java.io.IOException; |
| import java.io.StringReader; |
| import java.util.Arrays; |
| import java.util.regex.PatternSyntaxException; |
| import javax.xml.parsers.DocumentBuilder; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import javax.xml.parsers.ParserConfigurationException; |
| import junit.framework.TestCase; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.xml.sax.InputSource; |
| import org.xml.sax.SAXException; |
| |
| /** |
| * Unit tests for BuildMetadataFromXml.java |
| * |
| * @author Philippe Liard |
| */ |
| public class BuildMetadataFromXmlTest extends TestCase { |
| |
| // Helper method that outputs a DOM element from a XML string. |
| private static Element parseXmlString(String xmlString) |
| throws ParserConfigurationException, SAXException, IOException { |
| DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); |
| DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); |
| InputSource inputSource = new InputSource(); |
| inputSource.setCharacterStream(new StringReader(xmlString)); |
| return documentBuilder.parse(inputSource).getDocumentElement(); |
| } |
| |
| // Tests validateRE(). |
| public void testValidateRERemovesWhiteSpaces() { |
| String input = " hello world "; |
| // Should remove all the white spaces contained in the provided string. |
| assertEquals("helloworld", BuildMetadataFromXml.validateRE(input, true)); |
| // Make sure it only happens when the last parameter is set to true. |
| assertEquals(" hello world ", BuildMetadataFromXml.validateRE(input, false)); |
| } |
| |
| public void testValidateREThrowsException() { |
| String invalidPattern = "["; |
| // Should throw an exception when an invalid pattern is provided independently of the last |
| // parameter (remove white spaces). |
| try { |
| BuildMetadataFromXml.validateRE(invalidPattern, false); |
| fail(); |
| } catch (PatternSyntaxException e) { |
| // Test passed. |
| } |
| try { |
| BuildMetadataFromXml.validateRE(invalidPattern, true); |
| fail(); |
| } catch (PatternSyntaxException e) { |
| // Test passed. |
| } |
| // We don't allow | to be followed by ) because it introduces bugs, since we typically use it at |
| // the end of each line and when a line is deleted, if the pipe from the previous line is not |
| // removed, we end up erroneously accepting an empty group as well. |
| String patternWithPipeFollowedByClosingParentheses = "|)"; |
| try { |
| BuildMetadataFromXml.validateRE(patternWithPipeFollowedByClosingParentheses, true); |
| fail(); |
| } catch (PatternSyntaxException e) { |
| // Test passed. |
| } |
| String patternWithPipeFollowedByNewLineAndClosingParentheses = "|\n)"; |
| try { |
| BuildMetadataFromXml.validateRE(patternWithPipeFollowedByNewLineAndClosingParentheses, true); |
| fail(); |
| } catch (PatternSyntaxException e) { |
| // Test passed. |
| } |
| } |
| |
| public void testValidateRE() { |
| String validPattern = "[a-zA-Z]d{1,9}"; |
| // The provided pattern should be left unchanged. |
| assertEquals(validPattern, BuildMetadataFromXml.validateRE(validPattern, false)); |
| } |
| |
| // Tests getNationalPrefix(). |
| public void testGetNationalPrefix() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<territory nationalPrefix='00'/>"; |
| Element territoryElement = parseXmlString(xmlInput); |
| assertEquals("00", BuildMetadataFromXml.getNationalPrefix(territoryElement)); |
| } |
| |
| // Tests loadTerritoryTagMetadata(). |
| public void testLoadTerritoryTagMetadata() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<territory" |
| + " countryCode='33' leadingDigits='2' internationalPrefix='00'" |
| + " preferredInternationalPrefix='00~11' nationalPrefixForParsing='0'" |
| + " nationalPrefixTransformRule='9$1'" // nationalPrefix manually injected. |
| + " preferredExtnPrefix=' x' mainCountryForCode='true'" |
| + " mobileNumberPortableRegion='true'>" |
| + "</territory>"; |
| Element territoryElement = parseXmlString(xmlInput); |
| PhoneMetadata.Builder phoneMetadata = |
| BuildMetadataFromXml.loadTerritoryTagMetadata("33", territoryElement, "0"); |
| assertEquals(33, phoneMetadata.getCountryCode()); |
| assertEquals("2", phoneMetadata.getLeadingDigits()); |
| assertEquals("00", phoneMetadata.getInternationalPrefix()); |
| assertEquals("00~11", phoneMetadata.getPreferredInternationalPrefix()); |
| assertEquals("0", phoneMetadata.getNationalPrefixForParsing()); |
| assertEquals("9$1", phoneMetadata.getNationalPrefixTransformRule()); |
| assertEquals("0", phoneMetadata.getNationalPrefix()); |
| assertEquals(" x", phoneMetadata.getPreferredExtnPrefix()); |
| assertTrue(phoneMetadata.getMainCountryForCode()); |
| assertTrue(phoneMetadata.isMobileNumberPortableRegion()); |
| } |
| |
| public void testLoadTerritoryTagMetadataSetsBooleanFieldsToFalseByDefault() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<territory countryCode='33'/>"; |
| Element territoryElement = parseXmlString(xmlInput); |
| PhoneMetadata.Builder phoneMetadata = |
| BuildMetadataFromXml.loadTerritoryTagMetadata("33", territoryElement, ""); |
| assertFalse(phoneMetadata.getMainCountryForCode()); |
| assertFalse(phoneMetadata.isMobileNumberPortableRegion()); |
| } |
| |
| public void testLoadTerritoryTagMetadataSetsNationalPrefixForParsingByDefault() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<territory countryCode='33'/>"; |
| Element territoryElement = parseXmlString(xmlInput); |
| PhoneMetadata.Builder phoneMetadata = |
| BuildMetadataFromXml.loadTerritoryTagMetadata("33", territoryElement, "00"); |
| // When unspecified, nationalPrefixForParsing defaults to nationalPrefix. |
| assertEquals("00", phoneMetadata.getNationalPrefix()); |
| assertEquals(phoneMetadata.getNationalPrefix(), phoneMetadata.getNationalPrefixForParsing()); |
| } |
| |
| public void testLoadTerritoryTagMetadataWithRequiredAttributesOnly() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<territory countryCode='33' internationalPrefix='00'/>"; |
| Element territoryElement = parseXmlString(xmlInput); |
| // Should not throw any exception. |
| BuildMetadataFromXml.loadTerritoryTagMetadata("33", territoryElement, ""); |
| } |
| |
| // Tests loadInternationalFormat(). |
| public void testLoadInternationalFormat() |
| throws ParserConfigurationException, SAXException, IOException { |
| String intlFormat = "$1 $2"; |
| String xmlInput = "<numberFormat><intlFormat>" + intlFormat + "</intlFormat></numberFormat>"; |
| Element numberFormatElement = parseXmlString(xmlInput); |
| PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); |
| NumberFormat nationalFormat = NumberFormat.newBuilder().build(); |
| |
| assertTrue(BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement, |
| nationalFormat)); |
| assertEquals(intlFormat, metadata.getIntlNumberFormat(0).getFormat()); |
| } |
| |
| public void testLoadInternationalFormatWithBothNationalAndIntlFormatsDefined() |
| throws ParserConfigurationException, SAXException, IOException { |
| String intlFormat = "$1 $2"; |
| String xmlInput = "<numberFormat><intlFormat>" + intlFormat + "</intlFormat></numberFormat>"; |
| Element numberFormatElement = parseXmlString(xmlInput); |
| PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); |
| NumberFormat.Builder nationalFormat = NumberFormat.newBuilder(); |
| nationalFormat.setFormat("$1"); |
| |
| assertTrue(BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement, |
| nationalFormat.build())); |
| assertEquals(intlFormat, metadata.getIntlNumberFormat(0).getFormat()); |
| } |
| |
| public void testLoadInternationalFormatExpectsOnlyOnePattern() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<numberFormat><intlFormat/><intlFormat/></numberFormat>"; |
| Element numberFormatElement = parseXmlString(xmlInput); |
| PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); |
| |
| // Should throw an exception as multiple intlFormats are provided. |
| try { |
| BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement, |
| NumberFormat.newBuilder().build()); |
| fail(); |
| } catch (RuntimeException e) { |
| // Test passed. |
| } |
| } |
| |
| public void testLoadInternationalFormatUsesNationalFormatByDefault() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<numberFormat></numberFormat>"; |
| Element numberFormatElement = parseXmlString(xmlInput); |
| PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); |
| NumberFormat.Builder nationalFormat = NumberFormat.newBuilder(); |
| String nationalPattern = "$1 $2 $3"; |
| nationalFormat.setFormat(nationalPattern); |
| |
| assertFalse(BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement, |
| nationalFormat.build())); |
| assertEquals(nationalPattern, metadata.getIntlNumberFormat(0).getFormat()); |
| } |
| |
| public void testLoadInternationalFormatCopiesNationalFormatData() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<numberFormat></numberFormat>"; |
| Element numberFormatElement = parseXmlString(xmlInput); |
| PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); |
| NumberFormat.Builder nationalFormat = NumberFormat.newBuilder(); |
| nationalFormat.setFormat("$1-$2"); |
| nationalFormat.setNationalPrefixOptionalWhenFormatting(true); |
| |
| assertFalse(BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement, |
| nationalFormat.build())); |
| assertTrue(metadata.getIntlNumberFormat(0).getNationalPrefixOptionalWhenFormatting()); |
| } |
| |
| public void testLoadNationalFormat() |
| throws ParserConfigurationException, SAXException, IOException { |
| String nationalFormat = "$1 $2"; |
| String xmlInput = String.format("<numberFormat><format>%s</format></numberFormat>", |
| nationalFormat); |
| Element numberFormatElement = parseXmlString(xmlInput); |
| PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); |
| NumberFormat.Builder numberFormat = NumberFormat.newBuilder(); |
| BuildMetadataFromXml.loadNationalFormat(metadata, numberFormatElement, numberFormat); |
| assertEquals(nationalFormat, numberFormat.getFormat()); |
| } |
| |
| public void testLoadNationalFormatRequiresFormat() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<numberFormat></numberFormat>"; |
| Element numberFormatElement = parseXmlString(xmlInput); |
| PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); |
| NumberFormat.Builder numberFormat = NumberFormat.newBuilder(); |
| |
| try { |
| BuildMetadataFromXml.loadNationalFormat(metadata, numberFormatElement, numberFormat); |
| fail(); |
| } catch (RuntimeException e) { |
| // Test passed. |
| } |
| } |
| |
| public void testLoadNationalFormatExpectsExactlyOneFormat() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<numberFormat><format/><format/></numberFormat>"; |
| Element numberFormatElement = parseXmlString(xmlInput); |
| PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); |
| NumberFormat.Builder numberFormat = NumberFormat.newBuilder(); |
| |
| try { |
| BuildMetadataFromXml.loadNationalFormat(metadata, numberFormatElement, numberFormat); |
| fail(); |
| } catch (RuntimeException e) { |
| // Test passed. |
| } |
| } |
| |
| // Tests loadAvailableFormats(). |
| public void testLoadAvailableFormats() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<territory>" |
| + " <availableFormats>" |
| + " <numberFormat nationalPrefixFormattingRule='($FG)'" |
| + " carrierCodeFormattingRule='$NP $CC ($FG)'>" |
| + " <format>$1 $2 $3</format>" |
| + " </numberFormat>" |
| + " </availableFormats>" |
| + "</territory>"; |
| Element element = parseXmlString(xmlInput); |
| PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); |
| BuildMetadataFromXml.loadAvailableFormats( |
| metadata, element, "0", "", false /* NP not optional */); |
| assertEquals("($1)", metadata.getNumberFormat(0).getNationalPrefixFormattingRule()); |
| assertEquals("0 $CC ($1)", metadata.getNumberFormat(0).getDomesticCarrierCodeFormattingRule()); |
| assertEquals("$1 $2 $3", metadata.getNumberFormat(0).getFormat()); |
| } |
| |
| public void testLoadAvailableFormatsPropagatesCarrierCodeFormattingRule() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = |
| "<territory carrierCodeFormattingRule='$NP $CC ($FG)'>" |
| + " <availableFormats>" |
| + " <numberFormat nationalPrefixFormattingRule='($FG)'>" |
| + " <format>$1 $2 $3</format>" |
| + " </numberFormat>" |
| + " </availableFormats>" |
| + "</territory>"; |
| Element element = parseXmlString(xmlInput); |
| PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); |
| BuildMetadataFromXml.loadAvailableFormats( |
| metadata, element, "0", "", false /* NP not optional */); |
| assertEquals("($1)", metadata.getNumberFormat(0).getNationalPrefixFormattingRule()); |
| assertEquals("0 $CC ($1)", metadata.getNumberFormat(0).getDomesticCarrierCodeFormattingRule()); |
| assertEquals("$1 $2 $3", metadata.getNumberFormat(0).getFormat()); |
| } |
| |
| public void testLoadAvailableFormatsSetsProvidedNationalPrefixFormattingRule() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<territory>" |
| + " <availableFormats>" |
| + " <numberFormat><format>$1 $2 $3</format></numberFormat>" |
| + " </availableFormats>" |
| + "</territory>"; |
| Element element = parseXmlString(xmlInput); |
| PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); |
| BuildMetadataFromXml.loadAvailableFormats( |
| metadata, element, "", "($1)", false /* NP not optional */); |
| assertEquals("($1)", metadata.getNumberFormat(0).getNationalPrefixFormattingRule()); |
| } |
| |
| public void testLoadAvailableFormatsClearsIntlFormat() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<territory>" |
| + " <availableFormats>" |
| + " <numberFormat><format>$1 $2 $3</format></numberFormat>" |
| + " </availableFormats>" |
| + "</territory>"; |
| Element element = parseXmlString(xmlInput); |
| PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); |
| BuildMetadataFromXml.loadAvailableFormats( |
| metadata, element, "0", "($1)", false /* NP not optional */); |
| assertEquals(0, metadata.getIntlNumberFormatCount()); |
| } |
| |
| public void testLoadAvailableFormatsHandlesMultipleNumberFormats() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<territory>" |
| + " <availableFormats>" |
| + " <numberFormat><format>$1 $2 $3</format></numberFormat>" |
| + " <numberFormat><format>$1-$2</format></numberFormat>" |
| + " </availableFormats>" |
| + "</territory>"; |
| Element element = parseXmlString(xmlInput); |
| PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); |
| BuildMetadataFromXml.loadAvailableFormats( |
| metadata, element, "0", "($1)", false /* NP not optional */); |
| assertEquals("$1 $2 $3", metadata.getNumberFormat(0).getFormat()); |
| assertEquals("$1-$2", metadata.getNumberFormat(1).getFormat()); |
| } |
| |
| public void testLoadInternationalFormatDoesNotSetIntlFormatWhenNA() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<numberFormat><intlFormat>NA</intlFormat></numberFormat>"; |
| Element numberFormatElement = parseXmlString(xmlInput); |
| PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); |
| NumberFormat.Builder nationalFormat = NumberFormat.newBuilder(); |
| nationalFormat.setFormat("$1 $2"); |
| |
| BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement, |
| nationalFormat.build()); |
| assertEquals(0, metadata.getIntlNumberFormatCount()); |
| } |
| |
| // Tests setLeadingDigitsPatterns(). |
| public void testSetLeadingDigitsPatterns() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<numberFormat>" |
| + "<leadingDigits>1</leadingDigits><leadingDigits>2</leadingDigits>" |
| + "</numberFormat>"; |
| Element numberFormatElement = parseXmlString(xmlInput); |
| NumberFormat.Builder numberFormat = NumberFormat.newBuilder(); |
| BuildMetadataFromXml.setLeadingDigitsPatterns(numberFormatElement, numberFormat); |
| |
| assertEquals("1", numberFormat.getLeadingDigitsPattern(0)); |
| assertEquals("2", numberFormat.getLeadingDigitsPattern(1)); |
| } |
| |
| // Tests setLeadingDigitsPatterns() in the case of international and national formatting rules |
| // being present but not both defined for this numberFormat - we don't want to add them twice. |
| public void testSetLeadingDigitsPatternsNotAddedTwiceWhenInternationalFormatsPresent() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<availableFormats>" |
| + " <numberFormat pattern=\"(1)(\\d{3})\">" |
| + " <leadingDigits>1</leadingDigits>" |
| + " <format>$1</format>" |
| + " </numberFormat>" |
| + " <numberFormat pattern=\"(2)(\\d{3})\">" |
| + " <leadingDigits>2</leadingDigits>" |
| + " <format>$1</format>" |
| + " <intlFormat>9-$1</intlFormat>" |
| + " </numberFormat>" |
| + "</availableFormats>"; |
| Element element = parseXmlString(xmlInput); |
| PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); |
| BuildMetadataFromXml.loadAvailableFormats( |
| metadata, element, "0", "", false /* NP not optional */); |
| assertEquals(1, metadata.getNumberFormat(0).leadingDigitsPatternSize()); |
| assertEquals(1, metadata.getNumberFormat(1).leadingDigitsPatternSize()); |
| // When we merge the national format rules into the international format rules, we shouldn't add |
| // the leading digit patterns multiple times. |
| assertEquals(1, metadata.getIntlNumberFormat(0).leadingDigitsPatternSize()); |
| assertEquals(1, metadata.getIntlNumberFormat(1).leadingDigitsPatternSize()); |
| } |
| |
| // Tests getNationalPrefixFormattingRuleFromElement(). |
| public void testGetNationalPrefixFormattingRuleFromElement() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<territory nationalPrefixFormattingRule='$NP$FG'/>"; |
| Element element = parseXmlString(xmlInput); |
| assertEquals("0$1", |
| BuildMetadataFromXml.getNationalPrefixFormattingRuleFromElement(element, "0")); |
| } |
| |
| // Tests getDomesticCarrierCodeFormattingRuleFromElement(). |
| public void testGetDomesticCarrierCodeFormattingRuleFromElement() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<territory carrierCodeFormattingRule='$NP$CC $FG'/>"; |
| Element element = parseXmlString(xmlInput); |
| assertEquals("0$CC $1", |
| BuildMetadataFromXml.getDomesticCarrierCodeFormattingRuleFromElement(element, |
| "0")); |
| } |
| |
| // Tests processPhoneNumberDescElement(). |
| public void testProcessPhoneNumberDescElementWithInvalidInput() |
| throws ParserConfigurationException, SAXException, IOException { |
| PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder(); |
| Element territoryElement = parseXmlString("<territory/>"); |
| PhoneNumberDesc.Builder phoneNumberDesc; |
| |
| phoneNumberDesc = BuildMetadataFromXml.processPhoneNumberDescElement( |
| generalDesc, territoryElement, "invalidType"); |
| assertFalse(phoneNumberDesc.hasNationalNumberPattern()); |
| } |
| |
| public void testProcessPhoneNumberDescElementOverridesGeneralDesc() |
| throws ParserConfigurationException, SAXException, IOException { |
| PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder(); |
| generalDesc.setNationalNumberPattern("\\d{8}"); |
| String xmlInput = "<territory><fixedLine>" |
| + " <nationalNumberPattern>\\d{6}</nationalNumberPattern>" |
| + "</fixedLine></territory>"; |
| Element territoryElement = parseXmlString(xmlInput); |
| PhoneNumberDesc.Builder phoneNumberDesc; |
| |
| phoneNumberDesc = BuildMetadataFromXml.processPhoneNumberDescElement( |
| generalDesc, territoryElement, "fixedLine"); |
| assertEquals("\\d{6}", phoneNumberDesc.getNationalNumberPattern()); |
| } |
| |
| public void testBuildPhoneMetadataCollection_liteBuild() throws Exception { |
| String xmlInput = |
| "<phoneNumberMetadata>" |
| + " <territories>" |
| + " <territory id=\"AM\" countryCode=\"374\" internationalPrefix=\"00\">" |
| + " <generalDesc>" |
| + " <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>" |
| + " </generalDesc>" |
| + " <fixedLine>" |
| + " <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>" |
| + " <possibleLengths national=\"8\" localOnly=\"5,6\"/>" |
| + " <exampleNumber>10123456</exampleNumber>" |
| + " </fixedLine>" |
| + " <mobile>" |
| + " <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>" |
| + " <possibleLengths national=\"8\" localOnly=\"5,6\"/>" |
| + " <exampleNumber>10123456</exampleNumber>" |
| + " </mobile>" |
| + " </territory>" |
| + " </territories>" |
| + "</phoneNumberMetadata>"; |
| Document document = parseXmlString(xmlInput).getOwnerDocument(); |
| |
| PhoneMetadataCollection metadataCollection = BuildMetadataFromXml.buildPhoneMetadataCollection( |
| document, |
| true, // liteBuild |
| false, // specialBuild |
| false, // isShortNumberMetadata |
| false); // isAlternateFormatsMetadata |
| |
| assertTrue(metadataCollection.getMetadataCount() == 1); |
| PhoneMetadata metadata = metadataCollection.getMetadataList().get(0); |
| assertTrue(metadata.hasGeneralDesc()); |
| assertFalse(metadata.getGeneralDesc().hasExampleNumber()); |
| // Some Phonemetadata.java implementations may have custom logic, so we ensure this |
| // implementation is doing the right thing by checking the value of the example number even when |
| // hasExampleNumber is false. |
| assertEquals("", metadata.getGeneralDesc().getExampleNumber()); |
| assertTrue(metadata.hasFixedLine()); |
| assertFalse(metadata.getFixedLine().hasExampleNumber()); |
| assertEquals("", metadata.getFixedLine().getExampleNumber()); |
| assertTrue(metadata.hasMobile()); |
| assertFalse(metadata.getMobile().hasExampleNumber()); |
| assertEquals("", metadata.getMobile().getExampleNumber()); |
| } |
| |
| public void testBuildPhoneMetadataCollection_specialBuild() throws Exception { |
| String xmlInput = |
| "<phoneNumberMetadata>" |
| + " <territories>" |
| + " <territory id=\"AM\" countryCode=\"374\" internationalPrefix=\"00\">" |
| + " <generalDesc>" |
| + " <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>" |
| + " </generalDesc>" |
| + " <fixedLine>" |
| + " <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>" |
| + " <possibleLengths national=\"8\" localOnly=\"5,6\"/>" |
| + " <exampleNumber>10123456</exampleNumber>" |
| + " </fixedLine>" |
| + " <mobile>" |
| + " <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>" |
| + " <possibleLengths national=\"8\" localOnly=\"5,6\"/>" |
| + " <exampleNumber>10123456</exampleNumber>" |
| + " </mobile>" |
| + " </territory>" |
| + " </territories>" |
| + "</phoneNumberMetadata>"; |
| Document document = parseXmlString(xmlInput).getOwnerDocument(); |
| |
| PhoneMetadataCollection metadataCollection = BuildMetadataFromXml.buildPhoneMetadataCollection( |
| document, |
| false, // liteBuild |
| true, // specialBuild |
| false, // isShortNumberMetadata |
| false); // isAlternateFormatsMetadata |
| |
| assertTrue(metadataCollection.getMetadataCount() == 1); |
| PhoneMetadata metadata = metadataCollection.getMetadataList().get(0); |
| assertTrue(metadata.hasGeneralDesc()); |
| assertFalse(metadata.getGeneralDesc().hasExampleNumber()); |
| // Some Phonemetadata.java implementations may have custom logic, so we ensure this |
| // implementation is doing the right thing by checking the value of the example number even when |
| // hasExampleNumber is false. |
| assertEquals("", metadata.getGeneralDesc().getExampleNumber()); |
| // TODO: Consider clearing fixed-line if empty after being filtered. |
| assertTrue(metadata.hasFixedLine()); |
| assertFalse(metadata.getFixedLine().hasExampleNumber()); |
| assertEquals("", metadata.getFixedLine().getExampleNumber()); |
| assertTrue(metadata.hasMobile()); |
| assertTrue(metadata.getMobile().hasExampleNumber()); |
| assertEquals("10123456", metadata.getMobile().getExampleNumber()); |
| } |
| |
| public void testBuildPhoneMetadataCollection_fullBuild() throws Exception { |
| String xmlInput = |
| "<phoneNumberMetadata>" |
| + " <territories>" |
| + " <territory id=\"AM\" countryCode=\"374\" internationalPrefix=\"00\">" |
| + " <generalDesc>" |
| + " <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>" |
| + " </generalDesc>" |
| + " <fixedLine>" |
| + " <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>" |
| + " <possibleLengths national=\"8\" localOnly=\"5,6\"/>" |
| + " <exampleNumber>10123456</exampleNumber>" |
| + " </fixedLine>" |
| + " <mobile>" |
| + " <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>" |
| + " <possibleLengths national=\"8\" localOnly=\"5,6\"/>" |
| + " <exampleNumber>10123456</exampleNumber>" |
| + " </mobile>" |
| + " </territory>" |
| + " </territories>" |
| + "</phoneNumberMetadata>"; |
| Document document = parseXmlString(xmlInput).getOwnerDocument(); |
| |
| PhoneMetadataCollection metadataCollection = BuildMetadataFromXml.buildPhoneMetadataCollection( |
| document, |
| false, // liteBuild |
| false, // specialBuild |
| false, // isShortNumberMetadata |
| false); // isAlternateFormatsMetadata |
| |
| assertTrue(metadataCollection.getMetadataCount() == 1); |
| PhoneMetadata metadata = metadataCollection.getMetadataList().get(0); |
| assertTrue(metadata.hasGeneralDesc()); |
| assertFalse(metadata.getGeneralDesc().hasExampleNumber()); |
| // Some Phonemetadata.java implementations may have custom logic, so we ensure this |
| // implementation is doing the right thing by checking the value of the example number even when |
| // hasExampleNumber is false. |
| assertEquals("", metadata.getGeneralDesc().getExampleNumber()); |
| assertTrue(metadata.hasFixedLine()); |
| assertTrue(metadata.getFixedLine().hasExampleNumber()); |
| assertEquals("10123456", metadata.getFixedLine().getExampleNumber()); |
| assertTrue(metadata.hasMobile()); |
| assertTrue(metadata.getMobile().hasExampleNumber()); |
| assertEquals("10123456", metadata.getMobile().getExampleNumber()); |
| } |
| |
| public void testProcessPhoneNumberDescOutputsExampleNumberByDefault() |
| throws ParserConfigurationException, SAXException, IOException { |
| PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder(); |
| String xmlInput = "<territory><fixedLine>" |
| + " <exampleNumber>01 01 01 01</exampleNumber>" |
| + "</fixedLine></territory>"; |
| Element territoryElement = parseXmlString(xmlInput); |
| PhoneNumberDesc.Builder phoneNumberDesc; |
| |
| phoneNumberDesc = BuildMetadataFromXml.processPhoneNumberDescElement( |
| generalDesc, territoryElement, "fixedLine"); |
| assertEquals("01 01 01 01", phoneNumberDesc.getExampleNumber()); |
| } |
| |
| public void testProcessPhoneNumberDescRemovesWhiteSpacesInPatterns() |
| throws ParserConfigurationException, SAXException, IOException { |
| PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder(); |
| String xmlInput = "<territory><fixedLine>" |
| + " <nationalNumberPattern>\t \\d { 6 } </nationalNumberPattern>" |
| + "</fixedLine></territory>"; |
| Element countryElement = parseXmlString(xmlInput); |
| PhoneNumberDesc.Builder phoneNumberDesc = BuildMetadataFromXml.processPhoneNumberDescElement( |
| generalDesc, countryElement, "fixedLine"); |
| assertEquals("\\d{6}", phoneNumberDesc.getNationalNumberPattern()); |
| } |
| |
| // Tests setRelevantDescPatterns(). |
| public void testSetRelevantDescPatternsSetsSameMobileAndFixedLinePattern() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<territory countryCode=\"33\">" |
| + " <fixedLine><nationalNumberPattern>\\d{6}</nationalNumberPattern></fixedLine>" |
| + " <mobile><nationalNumberPattern>\\d{6}</nationalNumberPattern></mobile>" |
| + "</territory>"; |
| Element territoryElement = parseXmlString(xmlInput); |
| PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); |
| // Should set sameMobileAndFixedPattern to true. |
| BuildMetadataFromXml.setRelevantDescPatterns(metadata, territoryElement, |
| false /* isShortNumberMetadata */); |
| assertTrue(metadata.getSameMobileAndFixedLinePattern()); |
| } |
| |
| public void testSetRelevantDescPatternsSetsAllDescriptionsForRegularLengthNumbers() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<territory countryCode=\"33\">" |
| + " <fixedLine><nationalNumberPattern>\\d{1}</nationalNumberPattern></fixedLine>" |
| + " <mobile><nationalNumberPattern>\\d{2}</nationalNumberPattern></mobile>" |
| + " <pager><nationalNumberPattern>\\d{3}</nationalNumberPattern></pager>" |
| + " <tollFree><nationalNumberPattern>\\d{4}</nationalNumberPattern></tollFree>" |
| + " <premiumRate><nationalNumberPattern>\\d{5}</nationalNumberPattern></premiumRate>" |
| + " <sharedCost><nationalNumberPattern>\\d{6}</nationalNumberPattern></sharedCost>" |
| + " <personalNumber><nationalNumberPattern>\\d{7}</nationalNumberPattern></personalNumber>" |
| + " <voip><nationalNumberPattern>\\d{8}</nationalNumberPattern></voip>" |
| + " <uan><nationalNumberPattern>\\d{9}</nationalNumberPattern></uan>" |
| + "</territory>"; |
| Element territoryElement = parseXmlString(xmlInput); |
| PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); |
| BuildMetadataFromXml.setRelevantDescPatterns(metadata, territoryElement, |
| false /* isShortNumberMetadata */); |
| assertEquals("\\d{1}", metadata.getFixedLine().getNationalNumberPattern()); |
| assertEquals("\\d{2}", metadata.getMobile().getNationalNumberPattern()); |
| assertEquals("\\d{3}", metadata.getPager().getNationalNumberPattern()); |
| assertEquals("\\d{4}", metadata.getTollFree().getNationalNumberPattern()); |
| assertEquals("\\d{5}", metadata.getPremiumRate().getNationalNumberPattern()); |
| assertEquals("\\d{6}", metadata.getSharedCost().getNationalNumberPattern()); |
| assertEquals("\\d{7}", metadata.getPersonalNumber().getNationalNumberPattern()); |
| assertEquals("\\d{8}", metadata.getVoip().getNationalNumberPattern()); |
| assertEquals("\\d{9}", metadata.getUan().getNationalNumberPattern()); |
| } |
| |
| public void testSetRelevantDescPatternsSetsAllDescriptionsForShortNumbers() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<territory ID=\"FR\">" |
| + " <tollFree><nationalNumberPattern>\\d{1}</nationalNumberPattern></tollFree>" |
| + " <standardRate><nationalNumberPattern>\\d{2}</nationalNumberPattern></standardRate>" |
| + " <premiumRate><nationalNumberPattern>\\d{3}</nationalNumberPattern></premiumRate>" |
| + " <shortCode><nationalNumberPattern>\\d{4}</nationalNumberPattern></shortCode>" |
| + " <carrierSpecific>" |
| + " <nationalNumberPattern>\\d{5}</nationalNumberPattern>" |
| + " </carrierSpecific>" |
| + " <smsServices>" |
| + " <nationalNumberPattern>\\d{6}</nationalNumberPattern>" |
| + " </smsServices>" |
| + "</territory>"; |
| Element territoryElement = parseXmlString(xmlInput); |
| PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); |
| BuildMetadataFromXml.setRelevantDescPatterns(metadata, territoryElement, |
| true /* isShortNumberMetadata */); |
| assertEquals("\\d{1}", metadata.getTollFree().getNationalNumberPattern()); |
| assertEquals("\\d{2}", metadata.getStandardRate().getNationalNumberPattern()); |
| assertEquals("\\d{3}", metadata.getPremiumRate().getNationalNumberPattern()); |
| assertEquals("\\d{4}", metadata.getShortCode().getNationalNumberPattern()); |
| assertEquals("\\d{5}", metadata.getCarrierSpecific().getNationalNumberPattern()); |
| assertEquals("\\d{6}", metadata.getSmsServices().getNationalNumberPattern()); |
| } |
| |
| public void testSetRelevantDescPatternsThrowsErrorIfTypePresentMultipleTimes() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<territory countryCode=\"33\">" |
| + " <fixedLine><nationalNumberPattern>\\d{6}</nationalNumberPattern></fixedLine>" |
| + " <fixedLine><nationalNumberPattern>\\d{6}</nationalNumberPattern></fixedLine>" |
| + "</territory>"; |
| Element territoryElement = parseXmlString(xmlInput); |
| PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); |
| try { |
| BuildMetadataFromXml.setRelevantDescPatterns(metadata, territoryElement, |
| false /* isShortNumberMetadata */); |
| fail("Fixed-line info present twice for France: we should fail."); |
| } catch (RuntimeException expected) { |
| assertEquals("Multiple elements with type fixedLine found.", expected.getMessage()); |
| } |
| } |
| |
| public void testAlternateFormatsOmitsDescPatterns() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<territory countryCode=\"33\">" |
| + " <availableFormats>" |
| + " <numberFormat pattern=\"(1)(\\d{3})\">" |
| + " <leadingDigits>1</leadingDigits>" |
| + " <format>$1</format>" |
| + " </numberFormat>" |
| + " </availableFormats>" |
| + " <fixedLine><nationalNumberPattern>\\d{1}</nationalNumberPattern></fixedLine>" |
| + " <shortCode><nationalNumberPattern>\\d{2}</nationalNumberPattern></shortCode>" |
| + "</territory>"; |
| Element territoryElement = parseXmlString(xmlInput); |
| PhoneMetadata metadata = BuildMetadataFromXml.loadCountryMetadata("FR", territoryElement, |
| false /* isShortNumberMetadata */, true /* isAlternateFormatsMetadata */).build(); |
| assertEquals("(1)(\\d{3})", metadata.getNumberFormat(0).getPattern()); |
| assertEquals("1", metadata.getNumberFormat(0).getLeadingDigitsPattern(0)); |
| assertEquals("$1", metadata.getNumberFormat(0).getFormat()); |
| assertFalse(metadata.hasFixedLine()); |
| assertNull(metadata.getFixedLine()); |
| assertFalse(metadata.hasShortCode()); |
| assertNull(metadata.getShortCode()); |
| } |
| |
| public void testNationalPrefixRulesSetCorrectly() |
| throws ParserConfigurationException, SAXException, IOException { |
| String xmlInput = "<territory countryCode=\"33\" nationalPrefix=\"0\"" |
| + " nationalPrefixFormattingRule=\"$NP$FG\">" |
| + " <availableFormats>" |
| + " <numberFormat pattern=\"(1)(\\d{3})\" nationalPrefixOptionalWhenFormatting=\"true\">" |
| + " <leadingDigits>1</leadingDigits>" |
| + " <format>$1</format>" |
| + " </numberFormat>" |
| + " <numberFormat pattern=\"(\\d{3})\" nationalPrefixOptionalWhenFormatting=\"false\">" |
| + " <leadingDigits>2</leadingDigits>" |
| + " <format>$1</format>" |
| + " </numberFormat>" |
| + " </availableFormats>" |
| + " <fixedLine><nationalNumberPattern>\\d{1}</nationalNumberPattern></fixedLine>" |
| + "</territory>"; |
| Element territoryElement = parseXmlString(xmlInput); |
| PhoneMetadata metadata = BuildMetadataFromXml.loadCountryMetadata("FR", territoryElement, |
| false /* isShortNumberMetadata */, true /* isAlternateFormatsMetadata */).build(); |
| assertTrue(metadata.getNumberFormat(0).getNationalPrefixOptionalWhenFormatting()); |
| // This is inherited from the territory, with $NP replaced by the actual national prefix, and |
| // $FG replaced with $1. |
| assertEquals("0$1", metadata.getNumberFormat(0).getNationalPrefixFormattingRule()); |
| // Here it is explicitly set to false. |
| assertFalse(metadata.getNumberFormat(1).getNationalPrefixOptionalWhenFormatting()); |
| } |
| |
| public void testProcessPhoneNumberDescElement_PossibleLengthsSetCorrectly() throws Exception { |
| PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder(); |
| // The number lengths set for the general description must be a super-set of those in the |
| // element being parsed. |
| generalDesc.addPossibleLength(4); |
| generalDesc.addPossibleLength(6); |
| generalDesc.addPossibleLength(7); |
| generalDesc.addPossibleLength(13); |
| Element territoryElement = parseXmlString("<territory>" |
| + "<fixedLine>" |
| // Sorting will be done when parsing. |
| + " <possibleLengths national=\"13,4\" localOnly=\"6\"/>" |
| + "</fixedLine>" |
| + "</territory>"); |
| |
| PhoneNumberDesc.Builder fixedLine; |
| PhoneNumberDesc.Builder mobile; |
| |
| fixedLine = BuildMetadataFromXml.processPhoneNumberDescElement( |
| generalDesc, territoryElement, "fixedLine"); |
| mobile = BuildMetadataFromXml.processPhoneNumberDescElement( |
| generalDesc, territoryElement, "mobile"); |
| |
| assertEquals(2, fixedLine.getPossibleLengthCount()); |
| assertEquals(4, fixedLine.getPossibleLength(0)); |
| assertEquals(13, fixedLine.getPossibleLength(1)); |
| assertEquals(1, fixedLine.getPossibleLengthLocalOnlyCount()); |
| |
| // We use [-1] to denote that there are no possible lengths; we don't leave it empty, since for |
| // compression reasons, we use the empty list to mean that the generalDesc possible lengths |
| // apply. |
| assertEquals(1, mobile.getPossibleLengthCount()); |
| assertEquals(-1, mobile.getPossibleLength(0)); |
| assertEquals(0, mobile.getPossibleLengthLocalOnlyCount()); |
| } |
| |
| public void testSetPossibleLengthsGeneralDesc_BuiltFromChildElements() throws Exception { |
| Element territoryElement = parseXmlString("<territory>" |
| + "<fixedLine>" |
| + " <possibleLengths national=\"13\" localOnly=\"6\"/>" |
| + "</fixedLine>" |
| + "<mobile>" |
| + " <possibleLengths national=\"15\" localOnly=\"7,13\"/>" |
| + "</mobile>" |
| + "<tollFree>" |
| + " <possibleLengths national=\"15\"/>" |
| + "</tollFree>" |
| + "</territory>"); |
| PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder(); |
| BuildMetadataFromXml.setPossibleLengthsGeneralDesc( |
| generalDesc, "someId", territoryElement, false /* not short-number metadata */); |
| |
| assertEquals(2, generalDesc.getPossibleLengthCount()); |
| assertEquals(13, generalDesc.getPossibleLength(0)); |
| // 15 is present twice in the input in different sections, but only once in the output. |
| assertEquals(15, generalDesc.getPossibleLength(1)); |
| assertEquals(2, generalDesc.getPossibleLengthLocalOnlyCount()); |
| assertEquals(6, generalDesc.getPossibleLengthLocalOnly(0)); |
| assertEquals(7, generalDesc.getPossibleLengthLocalOnly(1)); |
| // 13 is skipped as a "local only" length, since it is also present as a normal length. |
| } |
| |
| public void testSetPossibleLengthsGeneralDesc_IgnoresNoIntlDialling() throws Exception { |
| Element territoryElement = parseXmlString("<territory>" |
| + "<fixedLine>" |
| + " <possibleLengths national=\"13\"/>" |
| + "</fixedLine>" |
| + "<noInternationalDialling>" |
| + " <possibleLengths national=\"15\"/>" |
| + "</noInternationalDialling>" |
| + "</territory>"); |
| PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder(); |
| BuildMetadataFromXml.setPossibleLengthsGeneralDesc( |
| generalDesc, "someId", territoryElement, false /* not short-number metadata */); |
| |
| assertEquals(1, generalDesc.getPossibleLengthCount()); |
| assertEquals(13, generalDesc.getPossibleLength(0)); |
| // 15 is skipped because noInternationalDialling should not contribute to the general lengths; |
| // it isn't a particular "type" of number per se, it is a property that different types may |
| // have. |
| } |
| |
| public void testSetPossibleLengthsGeneralDesc_ShortNumberMetadata() throws Exception { |
| Element territoryElement = parseXmlString("<territory>" |
| + "<shortCode>" |
| + " <possibleLengths national=\"6,13\"/>" |
| + "</shortCode>" |
| + "<carrierSpecific>" |
| + " <possibleLengths national=\"7,13,15\"/>" |
| + "</carrierSpecific>" |
| + "<tollFree>" |
| + " <possibleLengths national=\"15\"/>" |
| + "</tollFree>" |
| + "<smsServices>" |
| + " <possibleLengths national=\"5\"/>" |
| + "</smsServices>" |
| + "</territory>"); |
| PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder(); |
| BuildMetadataFromXml.setPossibleLengthsGeneralDesc( |
| generalDesc, "someId", territoryElement, true /* short-number metadata */); |
| |
| // All elements other than shortCode are ignored when creating the general desc. |
| assertEquals(2, generalDesc.getPossibleLengthCount()); |
| assertEquals(6, generalDesc.getPossibleLength(0)); |
| assertEquals(13, generalDesc.getPossibleLength(1)); |
| } |
| |
| public void testSetPossibleLengthsGeneralDesc_ShortNumberMetadataErrorsOnLocalLengths() |
| throws Exception { |
| Element territoryElement = parseXmlString("<territory>" |
| + "<shortCode>" |
| + " <possibleLengths national=\"13\" localOnly=\"6\"/>" |
| + "</shortCode>" |
| + "</territory>"); |
| |
| PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder(); |
| try { |
| BuildMetadataFromXml.setPossibleLengthsGeneralDesc( |
| generalDesc, "someId", territoryElement, true /* short-number metadata */); |
| fail(); |
| } catch (RuntimeException expected) { |
| // This should be an error, localOnly is not permitted in short-code metadata. |
| assertEquals("Found local-only lengths in short-number metadata", expected.getMessage()); |
| } |
| } |
| |
| public void testProcessPhoneNumberDescElement_ErrorDuplicates() throws Exception { |
| PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder(); |
| generalDesc.addPossibleLength(6); |
| |
| Element territoryElement = parseXmlString("<territory>" |
| + "<mobile>" |
| + " <possibleLengths national=\"6,6\"/>" |
| + "</mobile>" |
| + "</territory>"); |
| |
| try { |
| BuildMetadataFromXml.processPhoneNumberDescElement(generalDesc, territoryElement, "mobile"); |
| fail("Invalid data seen: expected failure."); |
| } catch (RuntimeException expected) { |
| // This should be an error, 6 is seen twice. |
| assertEquals("Duplicate length element found (6) in possibleLength string 6,6", |
| expected.getMessage()); |
| } |
| } |
| |
| public void testProcessPhoneNumberDescElement_ErrorDuplicatesOneLocal() throws Exception { |
| PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder(); |
| generalDesc.addPossibleLength(6); |
| |
| Element territoryElement = parseXmlString("<territory>" |
| + "<mobile>" |
| + " <possibleLengths national=\"6\" localOnly=\"6\"/>" |
| + "</mobile>" |
| + "</territory>"); |
| |
| try { |
| BuildMetadataFromXml.processPhoneNumberDescElement(generalDesc, territoryElement, "mobile"); |
| fail("Invalid data seen: expected failure."); |
| } catch (RuntimeException expected) { |
| // This should be an error, 6 is seen twice. |
| assertEquals("Possible length(s) found specified as a normal and local-only length: [6]", |
| expected.getMessage()); |
| } |
| } |
| |
| public void testProcessPhoneNumberDescElement_ErrorUncoveredLengths() throws Exception { |
| PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder(); |
| generalDesc.addPossibleLength(4); |
| Element territoryElement = parseXmlString("<territory>" |
| + "<noInternationalDialling>" |
| // Sorting will be done when parsing. |
| + " <possibleLengths national=\"6,7,4\"/>" |
| + "</noInternationalDialling>" |
| + "</territory>"); |
| try { |
| BuildMetadataFromXml.processPhoneNumberDescElement( |
| generalDesc, territoryElement, "noInternationalDialling"); |
| fail("Lengths present not covered by the general desc: should fail."); |
| } catch (RuntimeException expected) { |
| // Lengths were present that the general description didn't know about. |
| assertTrue(expected.getMessage().contains("Out-of-range possible length")); |
| } |
| } |
| |
| public void testProcessPhoneNumberDescElement_SameAsParent() throws Exception { |
| PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder(); |
| // The number lengths set for the general description must be a super-set of those in the |
| // element being parsed. |
| generalDesc.addPossibleLength(4); |
| generalDesc.addPossibleLength(6); |
| generalDesc.addPossibleLength(7); |
| generalDesc.addPossibleLengthLocalOnly(2); |
| Element territoryElement = parseXmlString("<territory>" |
| + "<fixedLine>" |
| // Sorting will be done when parsing. |
| + " <possibleLengths national=\"6,7,4\" localOnly=\"2\"/>" |
| + "</fixedLine>" |
| + "</territory>"); |
| |
| PhoneNumberDesc.Builder phoneNumberDesc = BuildMetadataFromXml.processPhoneNumberDescElement( |
| generalDesc, territoryElement, "fixedLine"); |
| // No possible lengths should be present, because they match the general description. |
| assertEquals(0, phoneNumberDesc.getPossibleLengthCount()); |
| // Local-only lengths should be present for child elements such as fixed-line. |
| assertEquals(1, phoneNumberDesc.getPossibleLengthLocalOnlyCount()); |
| } |
| |
| public void testProcessPhoneNumberDescElement_InvalidNumber() throws Exception { |
| PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder(); |
| generalDesc.addPossibleLength(4); |
| Element territoryElement = parseXmlString("<territory>" |
| + "<fixedLine>" |
| + " <possibleLengths national=\"4d\"/>" |
| + "</fixedLine>" |
| + "</territory>"); |
| |
| try { |
| BuildMetadataFromXml.processPhoneNumberDescElement( |
| generalDesc, territoryElement, "fixedLine"); |
| fail("4d is not a number."); |
| } catch (NumberFormatException expected) { |
| assertEquals("For input string: \"4d\"", expected.getMessage()); |
| } |
| } |
| |
| public void testLoadCountryMetadata_GeneralDescHasNumberLengthsSet() throws Exception { |
| Element territoryElement = parseXmlString("<territory>" |
| + "<generalDesc>" |
| // This shouldn't be set, the possible lengths should be derived for generalDesc. |
| + " <possibleLengths national=\"4\"/>" |
| + "</generalDesc>" |
| + "<fixedLine>" |
| + " <possibleLengths national=\"4\"/>" |
| + "</fixedLine>" |
| + "</territory>"); |
| |
| try { |
| BuildMetadataFromXml.loadCountryMetadata("FR", territoryElement, |
| false /* isShortNumberMetadata */, false /* isAlternateFormatsMetadata */); |
| fail("Possible lengths explicitly set for generalDesc and should not be: we should fail."); |
| } catch (RuntimeException expected) { |
| assertEquals("Found possible lengths specified at general desc: this should be derived" |
| + " from child elements. Affected country: FR", expected.getMessage()); |
| } |
| } |
| |
| public void testProcessPhoneNumberDescElement_ErrorEmptyPossibleLengthStringAttribute() |
| throws Exception { |
| PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder(); |
| generalDesc.addPossibleLength(4); |
| Element territoryElement = parseXmlString("<territory>" |
| + "<fixedLine>" |
| + " <possibleLengths national=\"\"/>" |
| + "</fixedLine>" |
| + "</territory>"); |
| try { |
| BuildMetadataFromXml.processPhoneNumberDescElement( |
| generalDesc, territoryElement, "fixedLine"); |
| fail("Empty possible length string."); |
| } catch (RuntimeException expected) { |
| assertEquals("Empty possibleLength string found.", expected.getMessage()); |
| } |
| } |
| |
| public void testProcessPhoneNumberDescElement_ErrorRangeSpecifiedWithComma() |
| throws Exception { |
| PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder(); |
| generalDesc.addPossibleLength(4); |
| Element territoryElement = parseXmlString("<territory>" |
| + "<fixedLine>" |
| + " <possibleLengths national=\"[4,7]\"/>" |
| + "</fixedLine>" |
| + "</territory>"); |
| try { |
| BuildMetadataFromXml.processPhoneNumberDescElement( |
| generalDesc, territoryElement, "fixedLine"); |
| fail("Ranges shouldn't use a comma."); |
| } catch (RuntimeException expected) { |
| assertEquals("Missing end of range character in possible length string [4,7].", |
| expected.getMessage()); |
| } |
| } |
| |
| public void testProcessPhoneNumberDescElement_ErrorIncompleteRange() throws Exception { |
| PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder(); |
| generalDesc.addPossibleLength(4); |
| Element territoryElement = parseXmlString("<territory>" |
| + "<fixedLine>" |
| + " <possibleLengths national=\"[4-\"/>" |
| + "</fixedLine>" |
| + "</territory>"); |
| |
| try { |
| BuildMetadataFromXml.processPhoneNumberDescElement( |
| generalDesc, territoryElement, "fixedLine"); |
| fail("Should fail: range incomplete."); |
| } catch (RuntimeException expected) { |
| assertEquals("Missing end of range character in possible length string [4-.", |
| expected.getMessage()); |
| } |
| } |
| |
| public void testProcessPhoneNumberDescElement_ErrorNoDashInRange() throws Exception { |
| PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder(); |
| generalDesc.addPossibleLength(4); |
| Element territoryElement = parseXmlString("<territory>" |
| + "<fixedLine>" |
| + " <possibleLengths national=\"[4:10]\"/>" |
| + "</fixedLine>" |
| + "</territory>"); |
| |
| try { |
| BuildMetadataFromXml.processPhoneNumberDescElement( |
| generalDesc, territoryElement, "fixedLine"); |
| fail("Should fail: range incomplete."); |
| } catch (RuntimeException expected) { |
| assertEquals("Ranges must have exactly one - character: missing for [4:10].", |
| expected.getMessage()); |
| } |
| } |
| |
| public void testProcessPhoneNumberDescElement_ErrorRangeIsNotFromMinToMax() throws Exception { |
| PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder(); |
| generalDesc.addPossibleLength(4); |
| Element territoryElement = parseXmlString("<territory>" |
| + "<fixedLine>" |
| + " <possibleLengths national=\"[10-10]\"/>" |
| + "</fixedLine>" |
| + "</territory>"); |
| |
| try { |
| BuildMetadataFromXml.processPhoneNumberDescElement( |
| generalDesc, territoryElement, "fixedLine"); |
| fail("Should fail: range even."); |
| } catch (RuntimeException expected) { |
| assertEquals("The first number in a range should be two or more digits lower than the second." |
| + " Culprit possibleLength string: [10-10]", expected.getMessage()); |
| } |
| } |
| |
| public void testGetMetadataFilter() { |
| assertEquals(BuildMetadataFromXml.getMetadataFilter(false, false), |
| MetadataFilter.emptyFilter()); |
| assertEquals(BuildMetadataFromXml.getMetadataFilter(true, false), |
| MetadataFilter.forLiteBuild()); |
| assertEquals(BuildMetadataFromXml.getMetadataFilter(false, true), |
| MetadataFilter.forSpecialBuild()); |
| try { |
| BuildMetadataFromXml.getMetadataFilter(true, true); |
| fail("getMetadataFilter should fail when liteBuild and specialBuild are both set"); |
| } catch (RuntimeException e) { |
| // Test passed. |
| } |
| } |
| } |