diff --git a/java/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java b/java/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java
index b0e500de8..11b8ba08f 100644
--- a/java/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java
+++ b/java/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java
@@ -55,7 +55,7 @@ public class AsYouTypeFormatter {
// A pattern that is used to match character classes in regular expressions. An example of a
// character class is [1-4].
- private final Pattern CHARACTER_CLASS_PATTERN = Pattern.compile("\\[([^\\[\\]])*\\]");
+ private static final Pattern CHARACTER_CLASS_PATTERN = Pattern.compile("\\[([^\\[\\]])*\\]");
// Any digit in a regular expression that actually denotes a digit. For example, in the regular
// expression 80[0-2]\d{6,10}, the first 2 digits (8 and 0) are standalone digits, but the rest
// are not.
@@ -89,8 +89,8 @@ public class AsYouTypeFormatter {
private RegexCache regexCache = new RegexCache(64);
/**
- * Constructs a light-weight formatter which does no formatting, but outputs exactly what is
- * fed into the inputDigit method.
+ * Constructs an as-you-type formatter. Should be obtained from {@link
+ * PhoneNumberUtil#getAsYouTypeFormatter}.
*
* @param regionCode the country/region where the phone number is being entered
*/
@@ -102,6 +102,11 @@ public class AsYouTypeFormatter {
private void initializeCountrySpecificInfo(String regionCode) {
currentMetaData = phoneUtil.getMetadataForRegion(regionCode);
+ if (currentMetaData == null) {
+ // Set to a default instance of the metadata. This allows us to function with an incorrect
+ // region code, even if formatting only works for numbers specified with "+".
+ currentMetaData = new PhoneMetadata().setInternationalPrefix("NA");
+ }
nationalPrefixForParsing =
regexCache.getPatternForRegex(currentMetaData.getNationalPrefixForParsing());
internationalPrefix =
@@ -170,8 +175,12 @@ public class AsYouTypeFormatter {
// Replace any standalone digit (not the one in d{}) with \d
numberPattern = STANDALONE_DIGIT_PATTERN.matcher(numberPattern).replaceAll("\\\\d");
formattingTemplate.setLength(0);
- formattingTemplate.append(getFormattingTemplate(numberPattern, numberFormat));
- return true;
+ String tempTemplate = getFormattingTemplate(numberPattern, numberFormat);
+ if (tempTemplate.length() > nationalNumber.length()) {
+ formattingTemplate.append(tempTemplate);
+ return true;
+ }
+ return false;
}
// Gets a formatting template which could be used to efficiently format a partial number where
@@ -236,7 +245,7 @@ public class AsYouTypeFormatter {
return currentOutput;
}
- @SuppressWarnings(value = "fallthrough")
+ @SuppressWarnings("fallthrough")
private String inputDigitWithOptionToRememberPosition(char nextChar, boolean rememberPosition) {
accruedInput.append(nextChar);
if (rememberPosition) {
@@ -323,8 +332,7 @@ public class AsYouTypeFormatter {
if (!ableToFormat) {
return originalPosition;
}
- int accruedInputIndex = 0;
- int currentOutputIndex = 0;
+ int accruedInputIndex = 0, currentOutputIndex = 0;
int currentOutputLength = currentOutput.length();
while (accruedInputIndex < positionToRemember && currentOutputIndex < currentOutputLength) {
if (accruedInputWithoutFormatting.charAt(accruedInputIndex) ==
@@ -466,8 +474,13 @@ public class AsYouTypeFormatter {
formattingTemplate.replace(0, tempTemplate.length(), tempTemplate);
lastMatchPosition = digitMatcher.start();
return formattingTemplate.substring(0, lastMatchPosition + 1);
- } else { // More digits are entered than we could handle.
- ableToFormat = false;
+ } else {
+ if (possibleFormats.size() == 1) {
+ // More digits are entered than we could handle, and there are no other valid patterns to
+ // try.
+ ableToFormat = false;
+ } // else, we just reset the formatting pattern.
+ currentFormattingPattern = "";
return accruedInput.toString();
}
}
diff --git a/java/src/com/google/i18n/phonenumbers/PhoneNumberMatch.java b/java/src/com/google/i18n/phonenumbers/PhoneNumberMatch.java
new file mode 100644
index 000000000..b00a0e18d
--- /dev/null
+++ b/java/src/com/google/i18n/phonenumbers/PhoneNumberMatch.java
@@ -0,0 +1,124 @@
+/*
+ * 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;
+
+import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
+
+import java.util.Arrays;
+
+/**
+ * The immutable match of a phone number within a piece of text. Matches may be found using
+ * {@link PhoneNumberUtil#findNumbers}.
+ *
+ * A match consists of the {@linkplain #number() phone number} as well as the
+ * {@linkplain #start() start} and {@linkplain #end() end} offsets of the corresponding subsequence
+ * of the searched text. Use {@link #rawString()} to obtain a copy of the matched subsequence.
+ *
+ *
The following annotated example clarifies the relationship between the searched text, the
+ * match offsets, and the parsed number:
+
+ *
+ * CharSequence text = "Call me at +1 425 882-8080 for details.";
+ * RegionCode country = RegionCode.US;
+ * PhoneNumberUtil util = PhoneNumberUtil.getInstance();
+ *
+ * // Find the first phone number match:
+ * PhoneNumberMatch m = util.findNumbers(text, country).iterator().next();
+ *
+ * // rawString() contains the phone number as it appears in the text.
+ * "+1 425 882-8080".equals(m.rawString());
+ *
+ * // start() and end() define the range of the matched subsequence.
+ * CharSequence subsequence = text.subSequence(m.start(), m.end());
+ * "+1 425 882-8080".contentEquals(subsequence);
+ *
+ * // number() returns the the same result as PhoneNumberUtil.{@link PhoneNumberUtil#parse parse()}
+ * // invoked on rawString().
+ * util.parse(m.rawString(), country).equals(m.number());
+ *
+ *
+ * @author Tom Hofmann
+ */
+public final class PhoneNumberMatch {
+ /** The start index into the text. */
+ private final int start;
+ /** The raw substring matched. */
+ private final String match;
+ /** The matched phone number. */
+ private final PhoneNumber number;
+
+ /**
+ * Creates a new match.
+ *
+ * @param start the start index into the target text
+ * @param match the matched substring of the target text
+ * @param number the matched phone number
+ */
+ PhoneNumberMatch(int start, String match, PhoneNumber number) {
+ if (start < 0) {
+ throw new IllegalArgumentException("Start index must be >= 0.");
+ }
+ if (match == null || number == null) {
+ throw new NullPointerException();
+ }
+ this.start = start;
+ this.match = match;
+ this.number = number;
+ }
+
+ /** Returns the phone number matched by the receiver. */
+ public PhoneNumber number() {
+ return number;
+ }
+
+ /** Returns the start index of the matched phone number within the searched text. */
+ public int start() {
+ return start;
+ }
+
+ /** Returns the exclusive end index of the matched phone number within the searched text. */
+ public int end() {
+ return start + match.length();
+ }
+
+ /** Returns the raw string matched as a phone number in the searched text. */
+ public String rawString() {
+ return match;
+ }
+
+ @Override
+ public int hashCode() {
+ return Arrays.hashCode(new Object[]{start, match, number});
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof PhoneNumberMatch)) {
+ return false;
+ }
+ PhoneNumberMatch other = (PhoneNumberMatch) obj;
+ return match.equals(other.match) && (start == other.start) && number.equals(other.number);
+ }
+
+ @Override
+ public String toString() {
+ return "PhoneNumberMatch [" + start() + "," + end() + ") " + match;
+ }
+}
diff --git a/java/src/com/google/i18n/phonenumbers/PhoneNumberMatcher.java b/java/src/com/google/i18n/phonenumbers/PhoneNumberMatcher.java
new file mode 100644
index 000000000..5121c259f
--- /dev/null
+++ b/java/src/com/google/i18n/phonenumbers/PhoneNumberMatcher.java
@@ -0,0 +1,339 @@
+/*
+ * 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;
+
+import com.google.i18n.phonenumbers.PhoneNumberUtil.Leniency;
+import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * A stateful class that finds and extracts telephone numbers from {@linkplain CharSequence text}.
+ * Instances can be created using the {@linkplain PhoneNumberUtil#findNumbers factory methods} in
+ * {@link PhoneNumberUtil}.
+ *
+ * Vanity numbers (phone numbers using alphabetic digits such as 1-800-SIX-FLAGS are
+ * not found.
+ *
+ *
This class is not thread-safe.
+ *
+ * @author Tom Hofmann
+ */
+final class PhoneNumberMatcher implements Iterator {
+ /**
+ * The phone number pattern used by {@link #find}, similar to
+ * {@code PhoneNumberUtil.VALID_PHONE_NUMBER}, but with the following differences:
+ *
+ * - All captures are limited in order to place an upper bound to the text matched by the
+ * pattern.
+ *
+ * - Leading punctuation / plus signs are limited.
+ *
- Consecutive occurrences of punctuation are limited.
+ *
- Number of digits is limited.
+ *
+ * - No whitespace is allowed at the start or end.
+ *
- No alpha digits (vanity numbers such as 1-800-SIX-FLAGS) are currently supported.
+ *
+ */
+ private static final Pattern PATTERN;
+ /**
+ * A phone number pattern that does not allow whitespace as punctuation. This pattern is only used
+ * in a second attempt to find a phone number occurring in the context of other numbers, such as
+ * when the preceding or following token is a zip code.
+ */
+ private static final Pattern INNER;
+ /**
+ * Matches strings that look like publication pages. Example:
+ * Computing Complete Answers to Queries in the Presence of Limited Access Patterns.
+ * Chen Li. VLDB J. 12(3): 211-227 (2003).
+ *
+ * The string "211-227 (2003)" is not a telephone number.
+ */
+ private static final Pattern PUB_PAGES = Pattern.compile("\\d{1,5}-+\\d{1,5}\\s{0,4}\\(\\d{1,4}");
+
+ static {
+ /* Builds the PATTERN and INNER regular expression patterns. The building blocks below
+ * exist to make the patterns more easily understood. */
+
+ /* Limit on the number of leading (plus) characters. */
+ String leadLimit = limit(0, 2);
+ /* Limit on the number of consecutive punctuation characters. */
+ String punctuationLimit = limit(0, 4);
+ /* The maximum number of digits allowed in a digit-separated block. As we allow all digits in a
+ * single block, set high enough to accommodate the entire national number and the international
+ * country code. */
+ int digitBlockLimit =
+ PhoneNumberUtil.MAX_LENGTH_FOR_NSN + PhoneNumberUtil.MAX_LENGTH_COUNTRY_CODE;
+ /* Limit on the number of blocks separated by punctuation. Use digitBlockLimit since in some
+ * formats use spaces to separate each digit. */
+ String blockLimit = limit(0, digitBlockLimit);
+
+ /* Same as {@link PhoneNumberUtil#VALID_PUNCTUATION} but without space characters. */
+ String nonSpacePunctuationChars = removeSpace(PhoneNumberUtil.VALID_PUNCTUATION);
+ /* A punctuation sequence without white space. */
+ String nonSpacePunctuation = "[" + nonSpacePunctuationChars + "]" + punctuationLimit;
+ /* A punctuation sequence allowing white space. */
+ String punctuation = "[" + PhoneNumberUtil.VALID_PUNCTUATION + "]" + punctuationLimit;
+ /* A digits block without punctuation. */
+ String digitSequence = "\\p{Nd}" + limit(1, digitBlockLimit);
+ /* Punctuation that may be at the start of a phone number - brackets and plus signs. */
+ String leadClass = "[(\\[" + PhoneNumberUtil.PLUS_CHARS + "]";
+
+ /* Phone number pattern allowing optional punctuation. */
+ PATTERN = Pattern.compile(
+ "(?:" + leadClass + punctuation + ")" + leadLimit +
+ digitSequence + "(?:" + punctuation + digitSequence + ")" + blockLimit +
+ "(?:" + PhoneNumberUtil.KNOWN_EXTN_PATTERNS + ")?",
+ PhoneNumberUtil.REGEX_FLAGS);
+
+ /* Phone number pattern with no whitespace allowed. */
+ INNER = Pattern.compile(
+ leadClass + leadLimit +
+ digitSequence + "(?:" + nonSpacePunctuation + digitSequence + ")" + blockLimit,
+ PhoneNumberUtil.REGEX_FLAGS);
+ }
+
+ /** Returns a regular expression quantifier with an upper and lower limit. */
+ private static String limit(int lower, int upper) {
+ if ((lower < 0) || (upper <= 0) || (upper < lower)) {
+ throw new IllegalArgumentException();
+ }
+ return "{" + lower + "," + upper + "}";
+ }
+
+ /**
+ * Returns a copy of {@code characters} with any {@linkplain Character#isSpaceChar space}
+ * characters removed.
+ */
+ private static String removeSpace(String characters) {
+ StringBuilder builder = new StringBuilder(characters.length());
+ int i = 0;
+ while (i < characters.length()) {
+ int codePoint = characters.codePointAt(i);
+ if (!Character.isSpaceChar(codePoint)) {
+ builder.appendCodePoint(codePoint);
+ }
+ i += Character.charCount(codePoint);
+ }
+ return builder.toString();
+ }
+
+ /** The potential states of a PhoneNumberMatcher. */
+ private enum State {
+ NOT_READY, READY, DONE
+ }
+
+ /** The phone number utility. */
+ private final PhoneNumberUtil util;
+ /** The text searched for phone numbers. */
+ private final CharSequence text;
+ /**
+ * The region (country) to assume for phone numbers without an international prefix, possibly
+ * null.
+ */
+ private final String preferredRegion;
+ /** The degree of validation requested. */
+ private final Leniency leniency;
+ /** The maximum number of retries after matching an invalid number. */
+ private long maxTries;
+
+ /** The iteration tristate. */
+ private State state = State.NOT_READY;
+ /** The last successful match, null unless in {@link State#READY}. */
+ private PhoneNumberMatch lastMatch = null;
+ /** The next index to start searching at. Undefined in {@link State#DONE}. */
+ private int searchIndex = 0;
+
+ /**
+ * Creates a new instance. See the factory methods in {@link PhoneNumberUtil} on how to obtain a
+ * new instance.
+ *
+ * @param util the phone number util to use
+ * @param text the character sequence that we will search, null for no text
+ * @param country the ISO 3166-1 two-letter country code indicating the country to assume for
+ * phone numbers not written in international format (with a leading plus, or
+ * with the international dialing prefix of the specified region). May be null or
+ * "ZZ" if only numbers with a leading plus should be considered.
+ * @param leniency the leniency to use when evaluating candidate phone numbers
+ * @param maxTries the maximum number of invalid numbers to try before giving up on the text.
+ * This is to cover degenerate cases where the text has a lot of false positives
+ * in it. Must be {@code >= 0}.
+ */
+ PhoneNumberMatcher(PhoneNumberUtil util, CharSequence text, String country, Leniency leniency,
+ long maxTries) {
+
+ if ((util == null) || (leniency == null)) {
+ throw new NullPointerException();
+ }
+ if (maxTries < 0) {
+ throw new IllegalArgumentException();
+ }
+ this.util = util;
+ this.text = (text != null) ? text : "";
+ this.preferredRegion = country;
+ this.leniency = leniency;
+ this.maxTries = maxTries;
+ }
+
+ @Override
+ public boolean hasNext() {
+ if (state == State.NOT_READY) {
+ lastMatch = find(searchIndex);
+ if (lastMatch == null) {
+ state = State.DONE;
+ } else {
+ searchIndex = lastMatch.end();
+ state = State.READY;
+ }
+ }
+ return state == State.READY;
+ }
+
+ @Override
+ public PhoneNumberMatch next() {
+ // Check the state and find the next match as a side-effect if necessary.
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ // Don't retain that memory any longer than necessary.
+ PhoneNumberMatch result = lastMatch;
+ lastMatch = null;
+ state = State.NOT_READY;
+ return result;
+ }
+
+ /**
+ * Attempts to find the next subsequence in the searched sequence on or after {@code searchIndex}
+ * that represents a phone number. Returns the next match, null if none was found.
+ *
+ * @param index the search index to start searching at
+ * @return the phone number match found, null if none can be found
+ */
+ private PhoneNumberMatch find(int index) {
+ Matcher matcher = PATTERN.matcher(text);
+ while ((maxTries > 0) && matcher.find(index)) {
+ int start = matcher.start();
+ CharSequence candidate = text.subSequence(start, matcher.end());
+
+ // Check for extra numbers at the end.
+ // TODO: This is the place to start when trying to support extraction of multiple phone number
+ // from split notations (+41 79 123 45 67 / 68).
+ candidate = trimAfterFirstMatch(PhoneNumberUtil.SECOND_NUMBER_START_PATTERN, candidate);
+
+ PhoneNumberMatch match = extractMatch(candidate, start);
+ if (match != null) {
+ return match;
+ }
+
+ index = start + candidate.length();
+ maxTries--;
+ }
+
+ return null;
+ }
+
+ /**
+ * Trims away any characters after the first match of {@code pattern} in {@code candidate},
+ * returning the trimmed version.
+ */
+ private static CharSequence trimAfterFirstMatch(Pattern pattern, CharSequence candidate) {
+ Matcher trailingCharsMatcher = pattern.matcher(candidate);
+ if (trailingCharsMatcher.find()) {
+ candidate = candidate.subSequence(0, trailingCharsMatcher.start());
+ }
+ return candidate;
+ }
+
+ /**
+ * Attempts to extract a match from a {@code candidate} character sequence.
+ *
+ * @param candidate the candidate text that might contain a phone number
+ * @param offset the offset of {@code candidate} within {@link #text}
+ * @return the match found, null if none can be found
+ */
+ private PhoneNumberMatch extractMatch(CharSequence candidate, int offset) {
+ // Skip a match that is more likely a publication page reference.
+ if (PUB_PAGES.matcher(candidate).find()) {
+ return null;
+ }
+
+ // Try to come up with a valid match given the entire candidate.
+ String rawString = candidate.toString();
+ PhoneNumberMatch match = parseAndVerify(rawString, offset);
+ if (match != null) {
+ return match;
+ }
+
+ // If that failed, try to find an inner match without white space.
+ return extractInnerMatch(rawString, offset);
+ }
+
+ /**
+ * Attempts to extract a match from {@code candidate} using the {@link #INNER} pattern.
+ *
+ * @param candidate the candidate text that might contain a phone number
+ * @param offset the offset of {@code candidate} within {@link #text}
+ * @return the match found, null if none can be found
+ */
+ private PhoneNumberMatch extractInnerMatch(String candidate, int offset) {
+ int index = 0;
+ Matcher matcher = INNER.matcher(candidate);
+ while ((maxTries > 0) && matcher.find(index)) {
+ String innerCandidate = candidate.substring(matcher.start(), matcher.end());
+ PhoneNumberMatch match = parseAndVerify(innerCandidate, offset + matcher.start());
+ if (match != null) {
+ return match;
+ }
+ maxTries--;
+ index = matcher.end();
+ }
+ return null;
+ }
+
+ /**
+ * Parses a phone number from the {@code candidate} using {@link PhoneNumberUtil#parse} and
+ * verifies it matches the requested {@link #leniency}. If parsing and verification succeed, a
+ * corresponding {@link PhoneNumberMatch} is returned, otherwise this method returns null.
+ *
+ * @param candidate the candidate match
+ * @param offset the offset of {@code candidate} within {@link #text}
+ * @return the parsed and validated phone number match, or null
+ */
+ private PhoneNumberMatch parseAndVerify(String candidate, int offset) {
+ try {
+ PhoneNumber number = util.parse(candidate, preferredRegion);
+ if (leniency.verify(number, util)) {
+ return new PhoneNumberMatch(offset, candidate, number);
+ }
+ } catch (NumberParseException e) {
+ // ignore and continue
+ }
+ return null;
+ }
+
+ /**
+ * Always throws {@link UnsupportedOperationException} as removal is not supported.
+ */
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/java/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java b/java/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java
index 9f0039203..df486bc80 100644
--- a/java/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java
+++ b/java/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java
@@ -23,14 +23,15 @@ import com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc;
import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber.CountryCodeSource;
-import java.io.InputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -56,8 +57,6 @@ public class PhoneNumberUtil {
static final int MAX_LENGTH_COUNTRY_CODE = 3;
static final String META_DATA_FILE_PREFIX =
"/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto";
- static final String COUNTRY_CODE_TO_REGION_CODE_MAP_CLASS_NAME =
- "CountryCodeToRegionCodeMap";
private String currentFilePrefix = META_DATA_FILE_PREFIX;
private static final Logger LOGGER = Logger.getLogger(PhoneNumberUtil.class.getName());
@@ -379,6 +378,36 @@ public class PhoneNumberUtil {
TOO_LONG,
}
+ /**
+ * Leniency when {@linkplain PhoneNumberUtil#findNumbers finding} potential phone numbers in text
+ * segments.
+ */
+ public enum Leniency {
+ /**
+ * Phone numbers accepted are {@linkplain PhoneNumberUtil#isPossibleNumber(PhoneNumber)
+ * possible}, but not necessarily {@linkplain PhoneNumberUtil#isValidNumber(PhoneNumber) valid}.
+ */
+ POSSIBLE {
+ @Override
+ boolean verify(PhoneNumber number, PhoneNumberUtil util) {
+ return util.isPossibleNumber(number);
+ }
+ },
+ /**
+ * Phone numbers accepted are {@linkplain PhoneNumberUtil#isPossibleNumber(PhoneNumber)
+ * possible} and {@linkplain PhoneNumberUtil#isValidNumber(PhoneNumber) valid}.
+ */
+ VALID {
+ @Override
+ boolean verify(PhoneNumber number, PhoneNumberUtil util) {
+ return util.isValidNumber(number);
+ }
+ };
+
+ /** Returns true if {@code number} is a verified number according to this leniency. */
+ abstract boolean verify(PhoneNumber number, PhoneNumberUtil util);
+ }
+
/**
* This class implements a singleton, so the only constructor is private.
*/
@@ -551,7 +580,7 @@ public class PhoneNumberUtil {
* - some geographical numbers have no area codes.
*
* @param number the PhoneNumber object for which clients want to know the length of the area
- * code in the national_number field.
+ * code.
* @return the length of area code of the PhoneNumber object passed in.
*/
public int getLengthOfGeographicalAreaCode(PhoneNumber number) {
@@ -829,6 +858,17 @@ public class PhoneNumberUtil {
return formattedNumber.toString();
}
+ /**
+ * Formats a phone number in national format for dialing using the carrier as specified in the
+ * carrierCode. The carrierCode will always be used regardless of whether the phone number already
+ * has a preferred domestic carrier code stored. If carrierCode contains an empty string, return
+ * the number in national format without any carrier code.
+ *
+ * @param number the phone number to be formatted
+ * @param carrierCode the carrier selection code to be used
+ * @return the formatted phone number in national format for dialing using the carrier as
+ * specified in the carrierCode
+ */
public String formatNationalNumberWithCarrierCode(PhoneNumber number, String carrierCode) {
int countryCode = number.getCountryCode();
String nationalSignificantNumber = getNationalSignificantNumber(number);
@@ -850,6 +890,29 @@ public class PhoneNumberUtil {
return formattedNumber.toString();
}
+ /**
+ * Formats a phone number in national format for dialing using the carrier as specified in the
+ * preferred_domestic_carrier_code field of the PhoneNumber object passed in. If that is missing,
+ * use the fallbackCarrierCode passed in instead. If there is no preferred_domestic_carrier_code,
+ * and the fallbackCarrierCode contains an empty string, return the number in national format
+ * without any carrier code.
+ *
+ * Use formatNationalNumberWithCarrierCode instead if the carrier code passed in should take
+ * precedence over the number's preferred_domestic_carrier_code when formatting.
+ *
+ * @param number the phone number to be formatted
+ * @param fallbackCarrierCode the carrier selection code to be used, if none is found in the
+ * phone number itself
+ * @return the formatted phone number in national format for dialing using the number's
+ * preferred_domestic_carrier_code, or the fallbackCarrierCode passed in if none is found
+ */
+ public String formatNationalNumberWithPreferredCarrierCode(PhoneNumber number,
+ String fallbackCarrierCode) {
+ return formatNationalNumberWithCarrierCode(number, number.hasPreferredDomesticCarrierCode()
+ ? number.getPreferredDomesticCarrierCode()
+ : fallbackCarrierCode);
+ }
+
/**
* Formats a phone number for out-of-country dialing purpose. If no countryCallingFrom
* is supplied, we format the number in its INTERNATIONAL format. If the countryCallingFrom is
@@ -1027,7 +1090,7 @@ public class PhoneNumberUtil {
}
// Note that carrierCode is optional - if NULL or an empty string, no carrier code replacement
- // will take place. Carrier code replacement occurs before national prefix replacement.
+ // will take place.
private String formatAccordingToFormats(String nationalNumber,
List availableFormats,
PhoneNumberFormat numberFormat,
@@ -1038,9 +1101,10 @@ public class PhoneNumberUtil {
// We always use the last leading_digits_pattern, as it is the most detailed.
numFormat.getLeadingDigitsPattern(size - 1)).matcher(nationalNumber).lookingAt()) {
Matcher m = regexCache.getPatternForRegex(numFormat.getPattern()).matcher(nationalNumber);
- String numberFormatRule = numFormat.getFormat();
if (m.matches()) {
- if (carrierCode != null && carrierCode.length() > 0 &&
+ String numberFormatRule = numFormat.getFormat();
+ if (numberFormat == PhoneNumberFormat.NATIONAL &&
+ carrierCode != null && carrierCode.length() > 0 &&
numFormat.getDomesticCarrierCodeFormattingRule().length() > 0) {
// Replace the $CC in the formatting rule with the desired carrier code.
String carrierCodeFormattingRule = numFormat.getDomesticCarrierCodeFormattingRule();
@@ -1050,15 +1114,18 @@ public class PhoneNumberUtil {
// combined in the appropriate way.
numberFormatRule = FIRST_GROUP_PATTERN.matcher(numberFormatRule)
.replaceFirst(carrierCodeFormattingRule);
- }
- String nationalPrefixFormattingRule = numFormat.getNationalPrefixFormattingRule();
- if (numberFormat == PhoneNumberFormat.NATIONAL &&
- nationalPrefixFormattingRule != null &&
- nationalPrefixFormattingRule.length() > 0) {
- Matcher firstGroupMatcher = FIRST_GROUP_PATTERN.matcher(numberFormatRule);
- return m.replaceAll(firstGroupMatcher.replaceFirst(nationalPrefixFormattingRule));
- } else {
return m.replaceAll(numberFormatRule);
+ } else {
+ // Use the national prefix formatting rule instead.
+ String nationalPrefixFormattingRule = numFormat.getNationalPrefixFormattingRule();
+ if (numberFormat == PhoneNumberFormat.NATIONAL &&
+ nationalPrefixFormattingRule != null &&
+ nationalPrefixFormattingRule.length() > 0) {
+ Matcher firstGroupMatcher = FIRST_GROUP_PATTERN.matcher(numberFormatRule);
+ return m.replaceAll(firstGroupMatcher.replaceFirst(nationalPrefixFormattingRule));
+ } else {
+ return m.replaceAll(numberFormatRule);
+ }
}
}
}
@@ -1565,15 +1632,15 @@ public class PhoneNumberUtil {
* @param nationalNumber a string buffer to store the national significant number in, in the case
* that a country code was extracted. The number is appended to any existing contents. If no
* country code was extracted, this will be left unchanged.
- * @param storeCountryCodeSource true if the country_code_source field of phoneNumber should be
- * populated.
+ * @param keepRawInput true if the country_code_source and preferred_carrier_code fields of
+ * phoneNumber should be populated.
* @param phoneNumber the PhoneNumber object that needs to be populated with country code and
* country code source. Note the country code is always populated, whereas country code source
* is only populated when keepCountryCodeSource is true.
* @return the country code extracted or 0 if none could be extracted
*/
int maybeExtractCountryCode(String number, PhoneMetadata defaultRegionMetadata,
- StringBuffer nationalNumber, boolean storeCountryCodeSource,
+ StringBuffer nationalNumber, boolean keepRawInput,
PhoneNumber phoneNumber)
throws NumberParseException {
if (number.length() == 0) {
@@ -1588,7 +1655,7 @@ public class PhoneNumberUtil {
CountryCodeSource countryCodeSource =
maybeStripInternationalPrefixAndNormalize(fullNumber, possibleCountryIddPrefix);
- if (storeCountryCodeSource) {
+ if (keepRawInput) {
phoneNumber.setCountryCodeSource(countryCodeSource);
}
if (countryCodeSource != CountryCodeSource.FROM_DEFAULT_COUNTRY) {
@@ -1621,11 +1688,7 @@ public class PhoneNumberUtil {
// If so, strip this, and see if the resultant number is valid.
StringBuffer potentialNationalNumber =
new StringBuffer(normalizedNumber.substring(defaultCountryCodeString.length()));
- maybeStripNationalPrefix(
- potentialNationalNumber,
- defaultRegionMetadata.getNationalPrefixForParsing(),
- defaultRegionMetadata.getNationalPrefixTransformRule(),
- validNumberPattern);
+ maybeStripNationalPrefixAndCarrierCode(potentialNationalNumber, defaultRegionMetadata);
Matcher possibleNumberMatcher =
regexCache.getPatternForRegex(generalDesc.getPossibleNumberPattern()).matcher(
potentialNationalNumber);
@@ -1635,7 +1698,7 @@ public class PhoneNumberUtil {
(possibleNumberMatcher.lookingAt() &&
possibleNumberMatcher.end() != potentialNationalNumber.length())) {
nationalNumber.append(potentialNationalNumber);
- if (storeCountryCodeSource) {
+ if (keepRawInput) {
phoneNumber.setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN);
}
phoneNumber.setCountryCode(defaultCountryCode);
@@ -1718,45 +1781,54 @@ public class PhoneNumberUtil {
*
* @param number the normalized telephone number that we wish to strip any national
* dialing prefix from
- * @param possibleNationalPrefix a regex that represents the national direct dialing prefix
- * from the country we think this number may be dialed in
- * @param transformRule the string that specifies how number should be transformed according
- * to the regex specified in possibleNationalPrefix
- * @param nationalNumberRule a regular expression that specifies what a valid phonenumber from
- * this region should look like after any national prefix was stripped or transformed
+ * @param metadata the metadata for the country that we think this number is from
+ * @return the carrier code extracted if it is present, otherwise return an empty string.
*/
- void maybeStripNationalPrefix(StringBuffer number, String possibleNationalPrefix,
- String transformRule, Pattern nationalNumberRule) {
+ String maybeStripNationalPrefixAndCarrierCode(StringBuffer number, PhoneMetadata metadata) {
+ String carrierCode = "";
int numberLength = number.length();
+ String possibleNationalPrefix = metadata.getNationalPrefixForParsing();
if (numberLength == 0 || possibleNationalPrefix.length() == 0) {
// Early return for numbers of zero length.
- return;
+ return carrierCode;
}
// Attempt to parse the first digits as a national prefix.
- Matcher m = regexCache.getPatternForRegex(possibleNationalPrefix).matcher(number);
- if (m.lookingAt()) {
- // m.group(1) == null implies nothing was captured by the capturing groups in
- // possibleNationalPrefix; therefore, no transformation is necessary, and we
- // just remove the national prefix.
- if (transformRule == null || transformRule.length() == 0 || m.group(1) == null) {
+ Matcher prefixMatcher = regexCache.getPatternForRegex(possibleNationalPrefix).matcher(number);
+ if (prefixMatcher.lookingAt()) {
+ Pattern nationalNumberRule =
+ regexCache.getPatternForRegex(metadata.getGeneralDesc().getNationalNumberPattern());
+ // prefixMatcher.group(numOfGroups) == null implies nothing was captured by the capturing
+ // groups in possibleNationalPrefix; therefore, no transformation is necessary, and we just
+ // remove the national prefix.
+ int numOfGroups = prefixMatcher.groupCount();
+ String transformRule = metadata.getNationalPrefixTransformRule();
+ if (transformRule == null || transformRule.length() == 0 ||
+ prefixMatcher.group(numOfGroups) == null) {
// Check that the resultant number is viable. If not, return.
- Matcher nationalNumber = nationalNumberRule.matcher(number.substring(m.end()));
+ Matcher nationalNumber = nationalNumberRule.matcher(number.substring(prefixMatcher.end()));
if (!nationalNumber.matches()) {
- return;
+ return carrierCode;
}
- number.delete(0, m.end());
+ if (numOfGroups > 0 && prefixMatcher.group(numOfGroups) != null) {
+ carrierCode = prefixMatcher.group(1);
+ }
+ number.delete(0, prefixMatcher.end());
} else {
// Check that the resultant number is viable. If not, return. Check this by copying the
// string buffer and making the transformation on the copy first.
StringBuffer transformedNumber = new StringBuffer(number);
- transformedNumber.replace(0, numberLength, m.replaceFirst(transformRule));
+ transformedNumber.replace(0, numberLength, prefixMatcher.replaceFirst(transformRule));
Matcher nationalNumber = nationalNumberRule.matcher(transformedNumber.toString());
if (!nationalNumber.matches()) {
- return;
+ return carrierCode;
+ }
+ if (numOfGroups > 1) {
+ carrierCode = prefixMatcher.group(1);
}
number.replace(0, number.length(), transformedNumber.toString());
}
}
+ return carrierCode;
}
/**
@@ -1842,11 +1914,11 @@ public class PhoneNumberUtil {
*
* @param numberToParse number that we are attempting to parse. This can contain formatting
* such as +, ( and -, as well as a phone number extension.
- * @param defaultCountry the ISO 3166-1 two-letter country code that denotes the
- * country that we are expecting the number to be from. This is only used
- * if the number being parsed is not written in international format.
- * The country code for the number in this case would be stored as that
- * of the default country supplied.
+ * @param defaultCountry the ISO 3166-1 two-letter country code that denotes the country that
+ * we are expecting the number to be from. This is only used if the
+ * number being parsed is not written in international format. The
+ * country code for the number in this case would be stored as that of
+ * the default country supplied.
* @return a phone number proto buffer filled with the parsed number
* @throws NumberParseException if the string is not considered to be a viable phone number or if
* no default country was supplied
@@ -1866,6 +1938,51 @@ public class PhoneNumberUtil {
parseHelper(numberToParse, defaultCountry, true, true, phoneNumber);
}
+ /**
+ * Returns an iterable over all {@link PhoneNumberMatch PhoneNumberMatches} in {@code text}. This
+ * is a shortcut for {@link #findNumbers(CharSequence, String, Leniency, long)
+ * getMatcher(text, defaultCountry, Leniency.VALID, Long.MAX_VALUE)}.
+ *
+ * @param text the text to search for phone numbers, null for no text
+ * @param defaultCountry the ISO 3166-1 two-letter country code that denotes the country that
+ * we are expecting the number to be from. This is only used if the
+ * number being parsed is not written in international format. The
+ * country code for the number in this case would be stored as that of
+ * the default country supplied. May be null if only international
+ * numbers are expected.
+ */
+ public Iterable findNumbers(CharSequence text, String defaultCountry) {
+ return findNumbers(text, defaultCountry, Leniency.VALID, Long.MAX_VALUE);
+ }
+
+ /**
+ * Returns an iterable over all {@link PhoneNumberMatch PhoneNumberMatches} in {@code text}.
+ *
+ * @param text the text to search for phone numbers, null for no text
+ * @param defaultCountry the ISO 3166-1 two-letter country code that denotes the country that
+ * we are expecting the number to be from. This is only used if the
+ * number being parsed is not written in international format. The
+ * country code for the number in this case would be stored as that of
+ * the default country supplied. May be null if only international
+ * numbers are expected.
+ * @param leniency the leniency to use when evaluating candidate phone numbers
+ * @param maxTries the maximum number of invalid numbers to try before giving up on the
+ * text. This is to cover degenerate cases where the text has a lot of
+ * false positives in it. Must be {@code >= 0}.
+ */
+ public Iterable findNumbers(
+ final CharSequence text, final String defaultCountry, final Leniency leniency,
+ final long maxTries) {
+
+ return new Iterable() {
+ @Override
+ public Iterator iterator() {
+ return new PhoneNumberMatcher(
+ PhoneNumberUtil.this, text, defaultCountry, leniency, maxTries);
+ }
+ };
+ }
+
/**
* Parses a string and fills up the phoneNumber. This method is the same as the public
* parse() method, with the exception that it allows the default country to be null, for use by
@@ -1933,13 +2050,11 @@ public class PhoneNumberUtil {
"The string supplied is too short to be a phone number.");
}
if (countryMetadata != null) {
- Pattern validNumberPattern =
- regexCache.getPatternForRegex(countryMetadata.getGeneralDesc()
- .getNationalNumberPattern());
- maybeStripNationalPrefix(normalizedNationalNumber,
- countryMetadata.getNationalPrefixForParsing(),
- countryMetadata.getNationalPrefixTransformRule(),
- validNumberPattern);
+ String carrierCode =
+ maybeStripNationalPrefixAndCarrierCode(normalizedNationalNumber, countryMetadata);
+ if (keepRawInput) {
+ phoneNumber.setPreferredDomesticCarrierCode(carrierCode);
+ }
}
int lengthOfNationalNumber = normalizedNationalNumber.length();
if (lengthOfNationalNumber < MIN_LENGTH_FOR_NSN) {
@@ -1983,12 +2098,14 @@ public class PhoneNumberUtil {
firstNumber.mergeFrom(firstNumberIn);
PhoneNumber secondNumber = new PhoneNumber();
secondNumber.mergeFrom(secondNumberIn);
- // First clear raw_input and country_code_source field and any empty-string extensions so that
- // we can use the PhoneNumber.exactlySameAs() method.
+ // First clear raw_input, country_code_source and preferred_domestic_carrier_code fields and any
+ // empty-string extensions so that we can use the proto-buffer equality method.
firstNumber.clearRawInput();
firstNumber.clearCountryCodeSource();
+ firstNumber.clearPreferredDomesticCarrierCode();
secondNumber.clearRawInput();
secondNumber.clearCountryCodeSource();
+ secondNumber.clearPreferredDomesticCarrierCode();
if (firstNumber.hasExtension() &&
firstNumber.getExtension().length() == 0) {
firstNumber.clearExtension();
diff --git a/java/src/com/google/i18n/phonenumbers/Phonenumber.java b/java/src/com/google/i18n/phonenumbers/Phonenumber.java
index 608a3b40b..89382a1f1 100644
--- a/java/src/com/google/i18n/phonenumbers/Phonenumber.java
+++ b/java/src/com/google/i18n/phonenumbers/Phonenumber.java
@@ -15,7 +15,7 @@
*/
/**
- * Definition of the class representing international telephone numbers. This class is hand created
+ * Definition of the class representing international telephone numbers. This class is hand-created
* based on the class file compiled from phonenumber.proto. Please refer to that file for detailed
* descriptions of the meaning of each field.
*/
@@ -141,6 +141,25 @@ public final class Phonenumber {
return this;
}
+ // optional string preferred_domestic_carrier_code = 7;
+ private boolean hasPreferredDomesticCarrierCode;
+ private java.lang.String preferredDomesticCarrierCode_ = "";
+ public boolean hasPreferredDomesticCarrierCode() { return hasPreferredDomesticCarrierCode; }
+ public String getPreferredDomesticCarrierCode() { return preferredDomesticCarrierCode_; }
+ public PhoneNumber setPreferredDomesticCarrierCode(String value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ hasPreferredDomesticCarrierCode = true;
+ preferredDomesticCarrierCode_ = value;
+ return this;
+ }
+ public PhoneNumber clearPreferredDomesticCarrierCode() {
+ hasPreferredDomesticCarrierCode = false;
+ preferredDomesticCarrierCode_ = "";
+ return this;
+ }
+
public final PhoneNumber clear() {
clearCountryCode();
clearNationalNumber();
@@ -148,6 +167,7 @@ public final class Phonenumber {
clearItalianLeadingZero();
clearRawInput();
clearCountryCodeSource();
+ clearPreferredDomesticCarrierCode();
return this;
}
@@ -170,6 +190,9 @@ public final class Phonenumber {
if (other.hasCountryCodeSource()) {
setCountryCodeSource(other.getCountryCodeSource());
}
+ if (other.hasPreferredDomesticCarrierCode()) {
+ setPreferredDomesticCarrierCode(other.getPreferredDomesticCarrierCode());
+ }
return this;
}
@@ -182,7 +205,9 @@ public final class Phonenumber {
}
return (countryCode_ == other.countryCode_ && nationalNumber_ == other.nationalNumber_ &&
extension_.equals(other.extension_) && italianLeadingZero_ == other.italianLeadingZero_ &&
- rawInput_.equals(other.rawInput_) && countryCodeSource_ == other.countryCodeSource_);
+ rawInput_.equals(other.rawInput_) && countryCodeSource_ == other.countryCodeSource_ &&
+ preferredDomesticCarrierCode_.equals(other.preferredDomesticCarrierCode_) &&
+ hasPreferredDomesticCarrierCode() == other.hasPreferredDomesticCarrierCode());
}
@Override
@@ -195,7 +220,7 @@ public final class Phonenumber {
// Simplified rendition of the hashCode function automatically generated from the proto
// compiler with java_generate_equals_and_hash set to true. We are happy with unset values to
// be considered equal to their explicitly-set equivalents, so don't check if any value is
- // unknown.
+ // unknown. The only exception to this is the preferred domestic carrier code.
int hash = 41;
hash = (53 * hash) + getCountryCode();
hash = (53 * hash) + Long.valueOf(getNationalNumber()).hashCode();
@@ -203,6 +228,8 @@ public final class Phonenumber {
hash = (53 * hash) + (getItalianLeadingZero() ? 1231 : 1237);
hash = (53 * hash) + getRawInput().hashCode();
hash = (53 * hash) + getCountryCodeSource().hashCode();
+ hash = (53 * hash) + getPreferredDomesticCarrierCode().hashCode();
+ hash = (53 * hash) + (hasPreferredDomesticCarrierCode() ? 1231 : 1237);
return hash;
}
@@ -220,6 +247,10 @@ public final class Phonenumber {
if (hasCountryCodeSource()) {
outputString.append(" Country Code Source: ").append(countryCodeSource_);
}
+ if (hasPreferredDomesticCarrierCode()) {
+ outputString.append(" Preferred Domestic Carrier Code: ").
+ append(preferredDomesticCarrierCode_);
+ }
return outputString.toString();
}
}
diff --git a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BF b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BF
index 1fc75cc6d..cd1431f15 100644
Binary files a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BF and b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BF differ
diff --git a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BO b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BO
index 191b55c7a..0395299f0 100644
Binary files a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BO and b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BO differ
diff --git a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BR b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BR
index 7fc1610f8..67fe311df 100644
Binary files a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BR and b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BR differ
diff --git a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CL b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CL
index e6bb05edf..2e9c0d8d6 100644
Binary files a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CL and b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CL differ
diff --git a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CO b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CO
index 84926a14e..e89645ad2 100644
Binary files a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CO and b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CO differ
diff --git a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CR b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CR
index 1b3a91c7a..979fa17cd 100644
Binary files a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CR and b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CR differ
diff --git a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DK b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DK
index 84b40d6e4..2b9a712c2 100644
Binary files a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DK and b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DK differ
diff --git a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FO b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FO
index f75752f4b..2d2ff1824 100644
Binary files a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FO and b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FO differ
diff --git a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GE b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GE
index fd894c53f..22f3da287 100644
Binary files a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GE and b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GE differ
diff --git a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KR b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KR
index 641ce7fce..e66f15795 100644
Binary files a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KR and b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KR differ
diff --git a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KW b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KW
index 3d5cd85f9..7ab6e3630 100644
Binary files a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KW and b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KW differ
diff --git a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LA b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LA
index e0c1ec1ca..984aeba23 100644
Binary files a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LA and b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LA differ
diff --git a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LU b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LU
index e3b025ff1..1b3137441 100644
Binary files a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LU and b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LU differ
diff --git a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MU b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MU
index 782c700fd..a65c8e327 100644
Binary files a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MU and b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MU differ
diff --git a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SC b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SC
index d8528060a..3d74da04d 100644
Binary files a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SC and b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SC differ
diff --git a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SH b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SH
index 96e6c73e7..c52c527ea 100644
Binary files a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SH and b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SH differ
diff --git a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TR b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TR
index 595e26cd3..0d20cbb59 100644
Binary files a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TR and b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TR differ
diff --git a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VE b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VE
index 3cc77d15a..96b653fcb 100644
Binary files a/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VE and b/java/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VE differ
diff --git a/java/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java b/java/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java
index 52db2a751..4920676a7 100644
--- a/java/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java
+++ b/java/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java
@@ -19,7 +19,7 @@ package com.google.i18n.phonenumbers;
import junit.framework.TestCase;
/**
- * Unit tests for PhoneNumberUtil.java
+ * Unit tests for AsYouTypeFormatter.java
*
* Note that these tests use the metadata contained in the files with TEST_META_DATA_FILE_PREFIX,
* not the normal metadata files, so should not be used for regression test purposes - these tests
@@ -31,7 +31,29 @@ public class AsYouTypeFormatterTest extends TestCase {
private PhoneNumberUtil phoneUtil;
public AsYouTypeFormatterTest() {
- phoneUtil = (new PhoneNumberUtilTest()).initilizePhoneUtilForTesting();
+ phoneUtil = PhoneNumberUtilTest.initializePhoneUtilForTesting();
+ }
+
+ public void testInvalidRegion() {
+ AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter("ZZ");
+ assertEquals("+", formatter.inputDigit('+'));
+ assertEquals("+4", formatter.inputDigit('4'));
+ assertEquals("+48 ", formatter.inputDigit('8'));
+ assertEquals("+48 8", formatter.inputDigit('8'));
+ assertEquals("+48 88", formatter.inputDigit('8'));
+ assertEquals("+48 88 1", formatter.inputDigit('1'));
+ assertEquals("+48 88 12", formatter.inputDigit('2'));
+ assertEquals("+48 88 123", formatter.inputDigit('3'));
+ assertEquals("+48 88 123 1", formatter.inputDigit('1'));
+ assertEquals("+48 88 123 12", formatter.inputDigit('2'));
+
+ formatter.clear();
+ assertEquals("6", formatter.inputDigit('6'));
+ assertEquals("65", formatter.inputDigit('5'));
+ assertEquals("650", formatter.inputDigit('0'));
+ assertEquals("6502", formatter.inputDigit('2'));
+ assertEquals("65025", formatter.inputDigit('5'));
+ assertEquals("650253", formatter.inputDigit('3'));
}
public void testAYTFUS() {
@@ -374,13 +396,25 @@ public class AsYouTypeFormatterTest extends TestCase {
assertEquals("030 123", formatter.inputDigit('3'));
assertEquals("030 1234", formatter.inputDigit('4'));
+ // 04134 1234
+ formatter.clear();
+ assertEquals("0", formatter.inputDigit('0'));
+ assertEquals("04", formatter.inputDigit('4'));
+ assertEquals("041", formatter.inputDigit('1'));
+ assertEquals("041 3", formatter.inputDigit('3'));
+ assertEquals("041 34", formatter.inputDigit('4'));
+ assertEquals("04134 1", formatter.inputDigit('1'));
+ assertEquals("04134 12", formatter.inputDigit('2'));
+ assertEquals("04134 123", formatter.inputDigit('3'));
+ assertEquals("04134 1234", formatter.inputDigit('4'));
+
// 08021 2345
formatter.clear();
assertEquals("0", formatter.inputDigit('0'));
assertEquals("08", formatter.inputDigit('8'));
assertEquals("080", formatter.inputDigit('0'));
- assertEquals("0802", formatter.inputDigit('2'));
- assertEquals("08021", formatter.inputDigit('1'));
+ assertEquals("080 2", formatter.inputDigit('2'));
+ assertEquals("080 21", formatter.inputDigit('1'));
assertEquals("08021 2", formatter.inputDigit('2'));
assertEquals("08021 23", formatter.inputDigit('3'));
assertEquals("08021 234", formatter.inputDigit('4'));
diff --git a/java/test/com/google/i18n/phonenumbers/PhoneNumberMatchTest.java b/java/test/com/google/i18n/phonenumbers/PhoneNumberMatchTest.java
new file mode 100644
index 000000000..6e1948785
--- /dev/null
+++ b/java/test/com/google/i18n/phonenumbers/PhoneNumberMatchTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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;
+
+import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link PhoneNumberMatch}.
+ *
+ * @author Tom Hofmann
+ */
+public class PhoneNumberMatchTest extends TestCase {
+ /**
+ * Tests the value type semantics. Equality and hash code must be based on the covered range and
+ * corresponding phone number. Range and number correctness are tested by
+ * {@link PhoneNumberMatcherTest}.
+ */
+ public void testValueTypeSemantics() throws Exception {
+ PhoneNumber number = new PhoneNumber();
+ PhoneNumberMatch match1 = new PhoneNumberMatch(10, "1 800 234 45 67", number);
+ PhoneNumberMatch match2 = new PhoneNumberMatch(10, "1 800 234 45 67", number);
+
+ assertEquals(match1, match2);
+ assertEquals(match1.hashCode(), match2.hashCode());
+ assertEquals(match1.start(), match2.start());
+ assertEquals(match1.end(), match2.end());
+ assertEquals(match1.number(), match2.number());
+ assertEquals(match1.rawString(), match2.rawString());
+ assertEquals("1 800 234 45 67", match1.rawString());
+ }
+
+ /**
+ * Tests the value type semantics for matches with a null number.
+ */
+ public void testIllegalArguments() throws Exception {
+ try {
+ new PhoneNumberMatch(-110, "1 800 234 45 67", new PhoneNumber());
+ fail();
+ } catch (IllegalArgumentException e) { /* success */ }
+
+ try {
+ new PhoneNumberMatch(10, "1 800 234 45 67", null);
+ fail();
+ } catch (NullPointerException e) { /* success */ }
+
+ try {
+ new PhoneNumberMatch(10, null, new PhoneNumber());
+ fail();
+ } catch (NullPointerException e) { /* success */ }
+
+ try {
+ new PhoneNumberMatch(10, null, null);
+ fail();
+ } catch (NullPointerException e) { /* success */ }
+ }
+}
diff --git a/java/test/com/google/i18n/phonenumbers/PhoneNumberMatcherTest.java b/java/test/com/google/i18n/phonenumbers/PhoneNumberMatcherTest.java
new file mode 100644
index 000000000..d0485f8d3
--- /dev/null
+++ b/java/test/com/google/i18n/phonenumbers/PhoneNumberMatcherTest.java
@@ -0,0 +1,540 @@
+/*
+ * 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;
+
+import com.google.i18n.phonenumbers.PhoneNumberUtil.Leniency;
+import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+/**
+ * Tests for {@link PhoneNumberMatcher}. This only tests basic functionality based on test metadata.
+ * See {@link PhoneNumberMatcherRegressionTest} for regression tests.
+ *
+ * @author Tom Hofmann
+ * @see PhoneNumberUtilTest {@link PhoneNumberUtilTest} for the origin of the test data
+ */
+public class PhoneNumberMatcherTest extends TestCase {
+ private PhoneNumberUtil phoneUtil;
+
+ @Override
+ protected void setUp() throws Exception {
+ phoneUtil = PhoneNumberUtilTest.initializePhoneUtilForTesting();
+ }
+
+ /** See {@link PhoneNumberUtilTest#testParseNationalNumber()}. */
+ public void testFindNationalNumber() throws Exception {
+ // same cases as in testParseNationalNumber
+ doTestFindInContext("033316005", "NZ");
+ doTestFindInContext("33316005", "NZ");
+ // National prefix attached and some formatting present.
+ doTestFindInContext("03-331 6005", "NZ");
+ doTestFindInContext("03 331 6005", "NZ");
+ // Testing international prefixes.
+ // Should strip country code.
+ doTestFindInContext("0064 3 331 6005", "NZ");
+ // Try again, but this time we have an international number with Region Code US. It should
+ // recognize the country code and parse accordingly.
+ doTestFindInContext("01164 3 331 6005", "US");
+ doTestFindInContext("+64 3 331 6005", "US");
+
+ doTestFindInContext("64(0)64123456", "NZ");
+ // Check that using a "/" is fine in a phone number.
+ doTestFindInContext("123/45678", "DE");
+ doTestFindInContext("123-456-7890", "US");
+ }
+
+ /** See {@link PhoneNumberUtilTest#testParseWithInternationalPrefixes()}. */
+ public void testFindWithInternationalPrefixes() throws Exception {
+ doTestFindInContext("+1 (650) 333-6000", "NZ");
+ doTestFindInContext("1-650-333-6000", "US");
+ // Calling the US number from Singapore by using different service providers
+ // 1st test: calling using SingTel IDD service (IDD is 001)
+ doTestFindInContext("0011-650-333-6000", "SG");
+ // 2nd test: calling using StarHub IDD service (IDD is 008)
+ doTestFindInContext("0081-650-333-6000", "SG");
+ // 3rd test: calling using SingTel V019 service (IDD is 019)
+ doTestFindInContext("0191-650-333-6000", "SG");
+ // Calling the US number from Poland
+ doTestFindInContext("0~01-650-333-6000", "PL");
+ // Using "++" at the start.
+ doTestFindInContext("++1 (650) 333-6000", "PL");
+ // Using a full-width plus sign.
+ doTestFindInContext("\uFF0B1 (650) 333-6000", "SG");
+ // The whole number, including punctuation, is here represented in full-width form.
+ doTestFindInContext("\uFF0B\uFF11\u3000\uFF08\uFF16\uFF15\uFF10\uFF09" +
+ "\u3000\uFF13\uFF13\uFF13\uFF0D\uFF16\uFF10\uFF10\uFF10",
+ "SG");
+ }
+
+ /** See {@link PhoneNumberUtilTest#testParseWithLeadingZero()}. */
+ public void testFindWithLeadingZero() throws Exception {
+ doTestFindInContext("+39 02-36618 300", "NZ");
+ doTestFindInContext("02-36618 300", "IT");
+ doTestFindInContext("312 345 678", "IT");
+ }
+
+ /** See {@link PhoneNumberUtilTest#testParseNationalNumberArgentina()}. */
+ public void testFindNationalNumberArgentina() throws Exception {
+ // Test parsing mobile numbers of Argentina.
+ doTestFindInContext("+54 9 343 555 1212", "AR");
+ doTestFindInContext("0343 15 555 1212", "AR");
+
+ doTestFindInContext("+54 9 3715 65 4320", "AR");
+ doTestFindInContext("03715 15 65 4320", "AR");
+
+ // Test parsing fixed-line numbers of Argentina.
+ doTestFindInContext("+54 11 3797 0000", "AR");
+ doTestFindInContext("011 3797 0000", "AR");
+
+ doTestFindInContext("+54 3715 65 4321", "AR");
+ doTestFindInContext("03715 65 4321", "AR");
+
+ doTestFindInContext("+54 23 1234 0000", "AR");
+ doTestFindInContext("023 1234 0000", "AR");
+ }
+
+ /** See {@link PhoneNumberUtilTest#testParseWithXInNumber()}. */
+ public void testFindWithXInNumber() throws Exception {
+ doTestFindInContext("(0xx) 123456789", "AR");
+
+ // This test is intentionally constructed such that the number of digit after xx is larger than
+ // 7, so that the number won't be mistakenly treated as an extension, as we allow extensions up
+ // to 7 digits. This assumption is okay for now as all the countries where a carrier selection
+ // code is written in the form of xx have a national significant number of length larger than 7.
+ doTestFindInContext("011xx5481429712", "US");
+ }
+
+ /** See {@link PhoneNumberUtilTest#testParseNumbersMexico()}. */
+ public void testFindNumbersMexico() throws Exception {
+ // Test parsing fixed-line numbers of Mexico.
+ doTestFindInContext("+52 (449)978-0001", "MX");
+ doTestFindInContext("01 (449)978-0001", "MX");
+ doTestFindInContext("(449)978-0001", "MX");
+
+ // Test parsing mobile numbers of Mexico.
+ doTestFindInContext("+52 1 33 1234-5678", "MX");
+ doTestFindInContext("044 (33) 1234-5678", "MX");
+ doTestFindInContext("045 33 1234-5678", "MX");
+ }
+
+ /** See {@link PhoneNumberUtilTest#testParseNumbersWithPlusWithNoRegion()}. */
+ public void testFindNumbersWithPlusWithNoRegion() throws Exception {
+ // "ZZ" is allowed only if the number starts with a '+' - then the country code can be
+ // calculated.
+ doTestFindInContext("+64 3 331 6005", "ZZ");
+ // Null is also allowed for the region code in these cases.
+ doTestFindInContext("+64 3 331 6005", null);
+ }
+
+ /** See {@link PhoneNumberUtilTest#testParseExtensions()}. */
+ public void testFindExtensions() throws Exception {
+ doTestFindInContext("03 331 6005 ext 3456", "NZ");
+ doTestFindInContext("03-3316005x3456", "NZ");
+ doTestFindInContext("03-3316005 int.3456", "NZ");
+ doTestFindInContext("03 3316005 #3456", "NZ");
+ doTestFindInContext("0~0 1800 7493 524", "PL");
+ doTestFindInContext("(1800) 7493.524", "US");
+ // Check that the last instance of an extension token is matched.
+ doTestFindInContext("0~0 1800 7493 524 ~1234", "PL");
+ // Verifying bug-fix where the last digit of a number was previously omitted if it was a 0 when
+ // extracting the extension. Also verifying a few different cases of extensions.
+ doTestFindInContext("+44 2034567890x456", "NZ");
+ doTestFindInContext("+44 2034567890x456", "GB");
+ doTestFindInContext("+44 2034567890 x456", "GB");
+ doTestFindInContext("+44 2034567890 X456", "GB");
+ doTestFindInContext("+44 2034567890 X 456", "GB");
+ doTestFindInContext("+44 2034567890 X 456", "GB");
+ doTestFindInContext("+44 2034567890 X 456", "GB");
+
+ doTestFindInContext("(800) 901-3355 x 7246433", "US");
+ doTestFindInContext("(800) 901-3355 , ext 7246433", "US");
+ doTestFindInContext("(800) 901-3355 ,extension 7246433", "US");
+ doTestFindInContext("(800) 901-3355 , 7246433", "US");
+ doTestFindInContext("(800) 901-3355 ext: 7246433", "US");
+ }
+
+ public void testFindInterspersedWithSpace() throws Exception {
+ doTestFindInContext("0 3 3 3 1 6 0 0 5", "NZ");
+ }
+
+ /**
+ * Test matching behavior when starting in the middle of a phone number.
+ */
+ public void testIntermediateParsePositions() throws Exception {
+ String text = "Call 033316005 or 032316005!";
+ // | | | | | |
+ // 0 5 10 15 20 25
+
+ // Iterate over all possible indices.
+ for (int i = 0; i <= 5; i++) {
+ assertEqualRange(text, i, 5, 14);
+ }
+ // 7 and 8 digits in a row are still parsed as number.
+ assertEqualRange(text, 6, 6, 14);
+ assertEqualRange(text, 7, 7, 14);
+ // Anything smaller is skipped to the second instance.
+ for (int i = 8; i <= 19; i++) {
+ assertEqualRange(text, i, 19, 28);
+ }
+ }
+
+ public void testNoMatchIfRegionIsNull() throws Exception {
+ // Fail on non-international prefix if region code is null.
+ assertTrue(hasNoMatches(phoneUtil.findNumbers(
+ "Random text body - number is 0331 6005, see you there", null)));
+ }
+
+ public void testNoMatchInEmptyString() throws Exception {
+ assertTrue(hasNoMatches(phoneUtil.findNumbers("", "US")));
+ assertTrue(hasNoMatches(phoneUtil.findNumbers(" ", "US")));
+ }
+
+ public void testNoMatchIfNoNumber() throws Exception {
+ assertTrue(hasNoMatches(phoneUtil.findNumbers(
+ "Random text body - number is foobar, see you there", "US")));
+ }
+
+ public void testSequences() throws Exception {
+ // Test multiple occurrences.
+ String text = "Call 033316005 or 032316005!";
+ String region = "NZ";
+
+ PhoneNumber number1 = new PhoneNumber();
+ number1.setCountryCode(phoneUtil.getCountryCodeForRegion(region));
+ number1.setNationalNumber(33316005);
+ PhoneNumberMatch match1 = new PhoneNumberMatch(5, "033316005", number1);
+
+ PhoneNumber number2 = new PhoneNumber();
+ number2.setCountryCode(phoneUtil.getCountryCodeForRegion(region));
+ number2.setNationalNumber(32316005);
+ PhoneNumberMatch match2 = new PhoneNumberMatch(19, "032316005", number2);
+
+ Iterator matches =
+ phoneUtil.findNumbers(text, region, Leniency.POSSIBLE, Long.MAX_VALUE).iterator();
+
+ assertEquals(match1, matches.next());
+ assertEquals(match2, matches.next());
+ }
+
+ public void testNullInput() throws Exception {
+ assertTrue(hasNoMatches(phoneUtil.findNumbers(null, "US")));
+ assertTrue(hasNoMatches(phoneUtil.findNumbers(null, null)));
+ }
+
+ public void testMaxMatches() throws Exception {
+ // Set up text with 100 valid phone numbers.
+ StringBuilder numbers = new StringBuilder();
+ for (int i = 0; i < 100; i++) {
+ numbers.append("My info: 415-666-7777,");
+ }
+
+ // Matches all 100. Max only applies to failed cases.
+ List expected = new ArrayList(100);
+ PhoneNumber number = phoneUtil.parse("+14156667777", null);
+ for (int i = 0; i < 100; i++) {
+ expected.add(number);
+ }
+
+ Iterable iterable =
+ phoneUtil.findNumbers(numbers.toString(), "US", Leniency.VALID, 10);
+ List actual = new ArrayList(100);
+ for (PhoneNumberMatch match : iterable) {
+ actual.add(match.number());
+ }
+ assertEquals(expected, actual);
+ }
+
+ public void testMaxMatchesInvalid() throws Exception {
+ // Set up text with 10 invalid phone numbers followed by 100 valid.
+ StringBuilder numbers = new StringBuilder();
+ for (int i = 0; i < 10; i++) {
+ numbers.append("My address 949-8945-0");
+ }
+ for (int i = 0; i < 100; i++) {
+ numbers.append("My info: 415-666-7777,");
+ }
+
+ Iterable iterable =
+ phoneUtil.findNumbers(numbers.toString(), "US", Leniency.VALID, 10);
+ assertFalse(iterable.iterator().hasNext());
+ }
+
+ public void testMaxMatchesMixed() throws Exception {
+ // Set up text with 100 valid numbers inside an invalid number.
+ StringBuilder numbers = new StringBuilder();
+ for (int i = 0; i < 100; i++) {
+ numbers.append("My info: 415-666-7777 123 fake street");
+ }
+
+ // Only matches the first 5 despite there being 100 numbers due to max matches.
+ // There are two false positives per line as "123" is also tried.
+ List expected = new ArrayList(100);
+ PhoneNumber number = phoneUtil.parse("+14156667777", null);
+ for (int i = 0; i < 5; i++) {
+ expected.add(number);
+ }
+
+ Iterable iterable =
+ phoneUtil.findNumbers(numbers.toString(), "US", Leniency.VALID, 10);
+ List actual = new ArrayList(100);
+ for (PhoneNumberMatch match : iterable) {
+ actual.add(match.number());
+ }
+ assertEquals(expected, actual);
+ }
+
+ public void testEmptyIteration() throws Exception {
+ Iterable iterable = phoneUtil.findNumbers("", "ZZ");
+ Iterator iterator = iterable.iterator();
+
+ assertFalse(iterator.hasNext());
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("Violation of the Iterator contract.");
+ } catch (NoSuchElementException e) { /* Success */ }
+ assertFalse(iterator.hasNext());
+ }
+
+ public void testSingleIteration() throws Exception {
+ Iterable iterable = phoneUtil.findNumbers("+14156667777", "ZZ");
+
+ // With hasNext() -> next().
+ Iterator iterator = iterable.iterator();
+ // Double hasNext() to ensure it does not advance.
+ assertTrue(iterator.hasNext());
+ assertTrue(iterator.hasNext());
+ assertNotNull(iterator.next());
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("Violation of the Iterator contract.");
+ } catch (NoSuchElementException e) { /* Success */ }
+ assertFalse(iterator.hasNext());
+
+ // With next() only.
+ iterator = iterable.iterator();
+ assertNotNull(iterator.next());
+ try {
+ iterator.next();
+ fail("Violation of the Iterator contract.");
+ } catch (NoSuchElementException e) { /* Success */ }
+ }
+
+ public void testDoubleIteration() throws Exception {
+ Iterable iterable =
+ phoneUtil.findNumbers("+14156667777 foobar +14156667777 ", "ZZ");
+
+ // With hasNext() -> next().
+ Iterator iterator = iterable.iterator();
+ // Double hasNext() to ensure it does not advance.
+ assertTrue(iterator.hasNext());
+ assertTrue(iterator.hasNext());
+ assertNotNull(iterator.next());
+ assertTrue(iterator.hasNext());
+ assertTrue(iterator.hasNext());
+ assertNotNull(iterator.next());
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("Violation of the Iterator contract.");
+ } catch (NoSuchElementException e) { /* Success */ }
+ assertFalse(iterator.hasNext());
+
+ // With next() only.
+ iterator = iterable.iterator();
+ assertNotNull(iterator.next());
+ assertNotNull(iterator.next());
+ try {
+ iterator.next();
+ fail("Violation of the Iterator contract.");
+ } catch (NoSuchElementException e) { /* Success */ }
+ }
+
+ /**
+ * Ensures that {@link Iterator#remove()} is not supported and that calling it does not
+ * change iteration behavior.
+ */
+ public void testRemovalNotSupported() throws Exception {
+ Iterable iterable = phoneUtil.findNumbers("+14156667777", "ZZ");
+
+ Iterator iterator = iterable.iterator();
+ try {
+ iterator.remove();
+ fail("Iterator must not support remove.");
+ } catch (UnsupportedOperationException e) { /* success */ }
+
+ assertTrue(iterator.hasNext());
+
+ try {
+ iterator.remove();
+ fail("Iterator must not support remove.");
+ } catch (UnsupportedOperationException e) { /* success */ }
+
+ assertNotNull(iterator.next());
+
+ try {
+ iterator.remove();
+ fail("Iterator must not support remove.");
+ } catch (UnsupportedOperationException e) { /* success */ }
+
+ assertFalse(iterator.hasNext());
+ }
+
+ /**
+ * Asserts that another number can be found in {@code text} starting at {@code index}, and that
+ * its corresponding range is {@code [start, end)}.
+ */
+ private void assertEqualRange(CharSequence text, int index, int start, int end) {
+ CharSequence sub = text.subSequence(index, text.length());
+ Iterator matches =
+ phoneUtil.findNumbers(sub, "NZ", Leniency.POSSIBLE, Long.MAX_VALUE).iterator();
+ assertTrue(matches.hasNext());
+ PhoneNumberMatch match = matches.next();
+ assertEquals(start - index, match.start());
+ assertEquals(end - index, match.end());
+ assertEquals(match.rawString(), sub.subSequence(match.start(), match.end()).toString());
+ }
+
+ /**
+ * Tests numbers found by {@link PhoneNumberUtil#find(CharSequence, String)} in various
+ * textual contexts.
+ *
+ * @param number the number to test and the corresponding region code to use
+ */
+ private void doTestFindInContext(String number, String defaultCountry) throws Exception {
+ findPossibleInContext(number, defaultCountry);
+
+ PhoneNumber parsed = phoneUtil.parse(number, defaultCountry);
+ if (phoneUtil.isValidNumber(parsed)) {
+ findValidInContext(number, defaultCountry);
+ }
+ }
+
+ private void findPossibleInContext(String number, String defaultCountry) {
+ ArrayList contextPairs = new ArrayList(15);
+ contextPairs.add(new NumberContext("", "")); // no context
+ contextPairs.add(new NumberContext(" ", "\t")); // whitespace only
+ contextPairs.add(new NumberContext("Hello ", "")); // no context at end
+ contextPairs.add(new NumberContext("", " to call me!")); // no context at start
+ contextPairs.add(new NumberContext("Hi there, call ", " to reach me!")); // no context at start
+ contextPairs.add(new NumberContext("Hi there, call ", ", or don't")); // with commas
+ // Three examples without whitespace around the number.
+ contextPairs.add(new NumberContext("Hi call", ""));
+ contextPairs.add(new NumberContext("", "forme"));
+ contextPairs.add(new NumberContext("Hi call", "forme"));
+ // With other small numbers.
+ contextPairs.add(new NumberContext("It's cheap! Call ", " before 6:30"));
+ // With a second number later.
+ contextPairs.add(new NumberContext("Call ", " or +1800-123-4567!"));
+ contextPairs.add(new NumberContext("Call me on June 21 at", "")); // with a Month-Day date
+ // With publication pages.
+ contextPairs.add(new NumberContext(
+ "As quoted by Alfonso 12-15 (2009), you may call me at ", ""));
+ contextPairs.add(new NumberContext(
+ "As quoted by Alfonso et al. 12-15 (2009), you may call me at ", ""));
+ // with a postfix stripped off as it looks like the start of another number
+ contextPairs.add(new NumberContext("Call ", "/x12 more"));
+
+ doTestInContext(number, defaultCountry, contextPairs, Leniency.POSSIBLE);
+ }
+
+ /**
+ * Tests valid numbers in contexts that fail for {@link Leniency#POSSIBLE}.
+ */
+ private void findValidInContext(String number, String defaultCountry) {
+ ArrayList contextPairs = new ArrayList(5);
+ // With other small numbers.
+ contextPairs.add(new NumberContext("It's only 9.99! Call ", " to buy"));
+ // With a number Day.Month.Year date.
+ contextPairs.add(new NumberContext("Call me on 21.6.1984 at ", ""));
+ // With a number Month/Day date.
+ contextPairs.add(new NumberContext("Call me on 06/21 at ", ""));
+ // With a number Day.Month date
+ contextPairs.add(new NumberContext("Call me on 21.6. at ", ""));
+ // With a number Month/Day/Year date.
+ contextPairs.add(new NumberContext("Call me on 06/21/84 at ", ""));
+ doTestInContext(number, defaultCountry, contextPairs, Leniency.VALID);
+ }
+
+ private void doTestInContext(String number, String defaultCountry,
+ List contextPairs, Leniency leniency) {
+ for (NumberContext context : contextPairs) {
+ String prefix = context.leadingText;
+ String text = prefix + number + context.trailingText;
+
+ int start = prefix.length();
+ int end = start + number.length();
+ Iterable iterable =
+ phoneUtil.findNumbers(text, defaultCountry, leniency, Long.MAX_VALUE);
+
+ PhoneNumberMatch match = iterable.iterator().hasNext() ? iterable.iterator().next() : null;
+ assertNotNull("Did not find a number in '" + text + "'; expected '" + number + "'", match);
+
+ CharSequence extracted = text.subSequence(match.start(), match.end());
+ assertTrue("Unexpected phone region in '" + text + "'; extracted '" + extracted + "'",
+ start == match.start() && end == match.end());
+ assertTrue(number.contentEquals(extracted));
+ assertTrue(match.rawString().contentEquals(extracted));
+
+ ensureTermination(text, defaultCountry, leniency);
+ }
+ }
+
+ /**
+ * Exhaustively searches for phone numbers from each index within {@code text} to test that
+ * finding matches always terminates.
+ */
+ private void ensureTermination(String text, String defaultCountry, Leniency leniency) {
+ for (int index = 0; index <= text.length(); index++) {
+ String sub = text.substring(index);
+ StringBuffer matches = new StringBuffer();
+ // Iterates over all matches.
+ for (PhoneNumberMatch match :
+ phoneUtil.findNumbers(sub, defaultCountry, leniency, Long.MAX_VALUE)) {
+ matches.append(", ").append(match.toString());
+ }
+ }
+ }
+
+ /**
+ * Returns true if there were no matches found.
+ */
+ private boolean hasNoMatches(Iterable iterable) {
+ return !iterable.iterator().hasNext();
+ }
+
+ /**
+ * Small class that holds the context of the number we are testing against. The test will
+ * insert the phone number to be found between leadingText and trailingText.
+ */
+ private class NumberContext {
+ final String leadingText;
+ final String trailingText;
+
+ NumberContext(String leadingText, String trailingText) {
+ this.leadingText = leadingText;
+ this.trailingText = trailingText;
+ }
+ }
+}
diff --git a/java/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java b/java/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java
index ffd6017b6..22941bca3 100644
--- a/java/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java
+++ b/java/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java
@@ -16,17 +16,17 @@
package com.google.i18n.phonenumbers;
+import com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
import com.google.i18n.phonenumbers.Phonemetadata.NumberFormat;
import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata;
+import com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc;
import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber.CountryCodeSource;
-import com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
import junit.framework.TestCase;
import java.util.ArrayList;
import java.util.List;
-import java.util.regex.Pattern;
/**
* Unit tests for PhoneNumberUtil.java
@@ -40,31 +40,67 @@ import java.util.regex.Pattern;
*/
public class PhoneNumberUtilTest extends TestCase {
private PhoneNumberUtil phoneUtil;
+ // This is used by BuildMetadataProtoFromXml.
static final String TEST_META_DATA_FILE_PREFIX =
"/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting";
- static final String TEST_COUNTRY_CODE_TO_REGION_CODE_MAP_CLASS_NAME =
- "CountryCodeToRegionCodeMapForTesting";
+
+ // Set up some test numbers to re-use.
+ private static final PhoneNumber ALPHA_NUMERIC_NUMBER =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(80074935247L);
+ private static final PhoneNumber AR_MOBILE =
+ new PhoneNumber().setCountryCode(54).setNationalNumber(91187654321L);
+ private static final PhoneNumber AR_NUMBER =
+ new PhoneNumber().setCountryCode(54).setNationalNumber(1187654321);
+ private static final PhoneNumber AU_NUMBER =
+ new PhoneNumber().setCountryCode(61).setNationalNumber(236618300L);
+ private static final PhoneNumber BS_MOBILE =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(2423570000L);
+ private static final PhoneNumber BS_NUMBER =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(2423651234L);
+ // Note that this is the same as the example number for DE in the metadata.
+ private static final PhoneNumber DE_NUMBER =
+ new PhoneNumber().setCountryCode(49).setNationalNumber(30123456L);
+ private static final PhoneNumber DE_SHORT_NUMBER =
+ new PhoneNumber().setCountryCode(49).setNationalNumber(1234L);
+ private static final PhoneNumber GB_MOBILE =
+ new PhoneNumber().setCountryCode(44).setNationalNumber(7912345678L);
+ private static final PhoneNumber GB_NUMBER =
+ new PhoneNumber().setCountryCode(44).setNationalNumber(2070313000L);
+ private static final PhoneNumber IT_MOBILE =
+ new PhoneNumber().setCountryCode(39).setNationalNumber(345678901L);
+ private static final PhoneNumber IT_NUMBER =
+ new PhoneNumber().setCountryCode(39).setNationalNumber(236618300L).
+ setItalianLeadingZero(true);
+ private static final PhoneNumber NZ_NUMBER =
+ new PhoneNumber().setCountryCode(64).setNationalNumber(33316005L);
+ private static final PhoneNumber SG_NUMBER =
+ new PhoneNumber().setCountryCode(65).setNationalNumber(65218000L);
+ // A too-long and hence invalid US number.
+ private static final PhoneNumber US_LONG_NUMBER =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(65025300001L);
+ private static final PhoneNumber US_NUMBER =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(6502530000L);
+ private static final PhoneNumber US_PREMIUM =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(9002530000L);
+ // Too short, but still possible US numbers.
+ private static final PhoneNumber US_LOCAL_NUMBER =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(2530000L);
+ private static final PhoneNumber US_SHORT_BY_ONE_NUMBER =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(650253000L);
+ private static final PhoneNumber US_TOLLFREE =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(8002530000L);
public PhoneNumberUtilTest() {
- phoneUtil = initilizePhoneUtilForTesting();
+ phoneUtil = initializePhoneUtilForTesting();
}
- PhoneNumberUtil initilizePhoneUtilForTesting() {
+ static PhoneNumberUtil initializePhoneUtilForTesting() {
PhoneNumberUtil.resetInstance();
- return PhoneNumberUtil.getInstance(TEST_META_DATA_FILE_PREFIX,
+ return PhoneNumberUtil.getInstance(
+ TEST_META_DATA_FILE_PREFIX,
CountryCodeToRegionCodeMapForTesting.getCountryCodeToRegionCodeMap());
}
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
public void testGetInstanceLoadUSMetadata() {
PhoneMetadata metadata = phoneUtil.getMetadataForRegion("US");
assertEquals("US", metadata.getId());
@@ -92,12 +128,12 @@ public class PhoneNumberUtilTest extends TestCase {
assertEquals(49, metadata.getCountryCode());
assertEquals("00", metadata.getInternationalPrefix());
assertEquals("0", metadata.getNationalPrefix());
- assertEquals(5, metadata.getNumberFormatCount());
- assertEquals(1, metadata.getNumberFormat(4).getLeadingDigitsPatternCount());
- assertEquals("900", metadata.getNumberFormat(4).getLeadingDigitsPattern(0));
+ assertEquals(6, metadata.getNumberFormatCount());
+ assertEquals(1, metadata.getNumberFormat(5).getLeadingDigitsPatternCount());
+ assertEquals("900", metadata.getNumberFormat(5).getLeadingDigitsPattern(0));
assertEquals("(\\d{3})(\\d{3,4})(\\d{4})",
- metadata.getNumberFormat(4).getPattern());
- assertEquals("$1 $2 $3", metadata.getNumberFormat(4).getFormat());
+ metadata.getNumberFormat(5).getPattern());
+ assertEquals("$1 $2 $3", metadata.getNumberFormat(5).getFormat());
assertEquals("(?:[24-6]\\d{2}|3[03-9]\\d|[789](?:[1-9]\\d|0[2-9]))\\d{3,8}",
metadata.getFixedLine().getNationalNumberPattern());
assertEquals("\\d{2,14}", metadata.getFixedLine().getPossibleNumberPattern());
@@ -123,104 +159,78 @@ public class PhoneNumberUtilTest extends TestCase {
}
public void testGetLengthOfGeographicalAreaCode() {
- PhoneNumber number = new PhoneNumber();
// Google MTV, which has area code "650".
- number.setCountryCode(1).setNationalNumber(6502530000L);
- assertEquals(3, phoneUtil.getLengthOfGeographicalAreaCode(number));
+ assertEquals(3, phoneUtil.getLengthOfGeographicalAreaCode(US_NUMBER));
// A North America toll-free number, which has no area code.
- number.setCountryCode(1).setNationalNumber(8002530000L);
- assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(number));
-
- // An invalid US number (1 digit shorter), which has no area code.
- number.setCountryCode(1).setNationalNumber(650253000L);
- assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(number));
+ assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(US_TOLLFREE));
// Google London, which has area code "20".
- number.setCountryCode(44).setNationalNumber(2070313000L);
- assertEquals(2, phoneUtil.getLengthOfGeographicalAreaCode(number));
+ assertEquals(2, phoneUtil.getLengthOfGeographicalAreaCode(GB_NUMBER));
// A UK mobile phone, which has no area code.
- number.setCountryCode(44).setNationalNumber(7123456789L);
- assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(number));
+ assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(GB_MOBILE));
// Google Buenos Aires, which has area code "11".
- number.setCountryCode(54).setNationalNumber(1155303000L);
- assertEquals(2, phoneUtil.getLengthOfGeographicalAreaCode(number));
+ assertEquals(2, phoneUtil.getLengthOfGeographicalAreaCode(AR_NUMBER));
// Google Sydney, which has area code "2".
- number.setCountryCode(61).setNationalNumber(293744000L);
- assertEquals(1, phoneUtil.getLengthOfGeographicalAreaCode(number));
+ assertEquals(1, phoneUtil.getLengthOfGeographicalAreaCode(AU_NUMBER));
// Google Singapore. Singapore has no area code and no national prefix.
- number.setCountryCode(65).setNationalNumber(65218000L);
- assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(number));
+ assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(SG_NUMBER));
+
+ // An invalid US number (1 digit shorter), which has no area code.
+ assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(US_SHORT_BY_ONE_NUMBER));
}
public void testGetLengthOfNationalDestinationCode() {
- PhoneNumber number = new PhoneNumber();
// Google MTV, which has national destination code (NDC) "650".
- number.setCountryCode(1).setNationalNumber(6502530000L);
- assertEquals(3, phoneUtil.getLengthOfNationalDestinationCode(number));
+ assertEquals(3, phoneUtil.getLengthOfNationalDestinationCode(US_NUMBER));
// A North America toll-free number, which has NDC "800".
- number.setCountryCode(1).setNationalNumber(8002530000L);
- assertEquals(3, phoneUtil.getLengthOfNationalDestinationCode(number));
+ assertEquals(3, phoneUtil.getLengthOfNationalDestinationCode(US_TOLLFREE));
// Google London, which has NDC "20".
- number.setCountryCode(44).setNationalNumber(2070313000L);
- assertEquals(2, phoneUtil.getLengthOfNationalDestinationCode(number));
+ assertEquals(2, phoneUtil.getLengthOfNationalDestinationCode(GB_NUMBER));
- // A UK mobile phone, which has NDC "7123".
- number.setCountryCode(44).setNationalNumber(7123456789L);
- assertEquals(4, phoneUtil.getLengthOfNationalDestinationCode(number));
+ // A UK mobile phone, which has NDC "7912".
+ assertEquals(4, phoneUtil.getLengthOfNationalDestinationCode(GB_MOBILE));
// Google Buenos Aires, which has NDC "11".
- number.setCountryCode(54).setNationalNumber(1155303000L);
- assertEquals(2, phoneUtil.getLengthOfNationalDestinationCode(number));
+ assertEquals(2, phoneUtil.getLengthOfNationalDestinationCode(AR_NUMBER));
// An Argentinian mobile which has NDC "911".
- number.setCountryCode(54).setNationalNumber(91155303001L);
- assertEquals(3, phoneUtil.getLengthOfNationalDestinationCode(number));
+ assertEquals(3, phoneUtil.getLengthOfNationalDestinationCode(AR_MOBILE));
// Google Sydney, which has NDC "2".
- number.setCountryCode(61).setNationalNumber(293744000L);
- assertEquals(1, phoneUtil.getLengthOfNationalDestinationCode(number));
+ assertEquals(1, phoneUtil.getLengthOfNationalDestinationCode(AU_NUMBER));
// Google Singapore, which has NDC "6521".
- number.setCountryCode(65).setNationalNumber(65218000L);
- assertEquals(4, phoneUtil.getLengthOfNationalDestinationCode(number));
+ assertEquals(4, phoneUtil.getLengthOfNationalDestinationCode(SG_NUMBER));
// An invalid US number (1 digit shorter), which has no NDC.
- number.setCountryCode(1).setNationalNumber(650253000L);
- assertEquals(0, phoneUtil.getLengthOfNationalDestinationCode(number));
+ assertEquals(0, phoneUtil.getLengthOfNationalDestinationCode(US_SHORT_BY_ONE_NUMBER));
// A number containing an invalid country code, which shouldn't have any NDC.
- number.setCountryCode(123).setNationalNumber(6502530000L);
+ PhoneNumber number = new PhoneNumber().setCountryCode(123).setNationalNumber(6502530000L);
assertEquals(0, phoneUtil.getLengthOfNationalDestinationCode(number));
}
public void testGetNationalSignificantNumber() {
- PhoneNumber number = new PhoneNumber();
- number.setCountryCode(1).setNationalNumber(6502530000L);
- assertEquals("6502530000", PhoneNumberUtil.getNationalSignificantNumber(number));
+ assertEquals("6502530000", PhoneNumberUtil.getNationalSignificantNumber(US_NUMBER));
// An Italian mobile number.
- number.setCountryCode(39).setNationalNumber(312345678L);
- assertEquals("312345678", PhoneNumberUtil.getNationalSignificantNumber(number));
+ assertEquals("345678901", PhoneNumberUtil.getNationalSignificantNumber(IT_MOBILE));
// An Italian fixed line number.
- number.setCountryCode(39).setNationalNumber(236618300L).setItalianLeadingZero(true);
- assertEquals("0236618300", PhoneNumberUtil.getNationalSignificantNumber(number));
+ assertEquals("0236618300", PhoneNumberUtil.getNationalSignificantNumber(IT_NUMBER));
}
public void testGetExampleNumber() {
- PhoneNumber deNumber = new PhoneNumber();
- deNumber.setCountryCode(49).setNationalNumber(30123456);
- assertEquals(deNumber, phoneUtil.getExampleNumber("DE"));
- assertEquals(deNumber, phoneUtil.getExampleNumber("de"));
+ assertEquals(DE_NUMBER, phoneUtil.getExampleNumber("DE"));
- assertEquals(deNumber,
+ assertEquals(DE_NUMBER,
phoneUtil.getExampleNumberForType("DE",
PhoneNumberUtil.PhoneNumberType.FIXED_LINE));
assertEquals(null,
@@ -273,49 +283,27 @@ public class PhoneNumberUtilTest extends TestCase {
}
public void testFormatUSNumber() {
- PhoneNumber usNumber = new PhoneNumber();
- usNumber.setCountryCode(1).setNationalNumber(6502530000L);
- assertEquals("650 253 0000", phoneUtil.format(usNumber, PhoneNumberFormat.NATIONAL));
- assertEquals("+1 650 253 0000", phoneUtil.format(usNumber, PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("650 253 0000", phoneUtil.format(US_NUMBER, PhoneNumberFormat.NATIONAL));
+ assertEquals("+1 650 253 0000", phoneUtil.format(US_NUMBER, PhoneNumberFormat.INTERNATIONAL));
- usNumber.clear();
- usNumber.setCountryCode(1).setNationalNumber(8002530000L);
- assertEquals("800 253 0000", phoneUtil.format(usNumber, PhoneNumberFormat.NATIONAL));
- assertEquals("+1 800 253 0000", phoneUtil.format(usNumber, PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("800 253 0000", phoneUtil.format(US_TOLLFREE, PhoneNumberFormat.NATIONAL));
+ assertEquals("+1 800 253 0000", phoneUtil.format(US_TOLLFREE, PhoneNumberFormat.INTERNATIONAL));
- usNumber.clear();
- usNumber.setCountryCode(1).setNationalNumber(9002530000L);
- assertEquals("900 253 0000", phoneUtil.format(usNumber, PhoneNumberFormat.NATIONAL));
- assertEquals("+1 900 253 0000", phoneUtil.format(usNumber, PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("900 253 0000", phoneUtil.format(US_PREMIUM, PhoneNumberFormat.NATIONAL));
+ assertEquals("+1 900 253 0000", phoneUtil.format(US_PREMIUM, PhoneNumberFormat.INTERNATIONAL));
}
public void testFormatBSNumber() {
- PhoneNumber bsNumber = new PhoneNumber();
- bsNumber.setCountryCode(1).setNationalNumber(2421234567L);
- assertEquals("242 123 4567", phoneUtil.format(bsNumber, PhoneNumberFormat.NATIONAL));
- assertEquals("+1 242 123 4567", phoneUtil.format(bsNumber, PhoneNumberFormat.INTERNATIONAL));
-
- bsNumber.clear();
- bsNumber.setCountryCode(1).setNationalNumber(8002530000L);
- assertEquals("800 253 0000", phoneUtil.format(bsNumber, PhoneNumberFormat.NATIONAL));
- assertEquals("+1 800 253 0000", phoneUtil.format(bsNumber, PhoneNumberFormat.INTERNATIONAL));
-
- bsNumber.clear();
- bsNumber.setCountryCode(1).setNationalNumber(9002530000L);
- assertEquals("900 253 0000", phoneUtil.format(bsNumber, PhoneNumberFormat.NATIONAL));
- assertEquals("+1 900 253 0000", phoneUtil.format(bsNumber, PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("242 365 1234", phoneUtil.format(BS_NUMBER, PhoneNumberFormat.NATIONAL));
+ assertEquals("+1 242 365 1234", phoneUtil.format(BS_NUMBER, PhoneNumberFormat.INTERNATIONAL));
}
public void testFormatGBNumber() {
- PhoneNumber gbNumber = new PhoneNumber();
- gbNumber.setCountryCode(44).setNationalNumber(2087389353L);
- assertEquals("(020) 8738 9353", phoneUtil.format(gbNumber, PhoneNumberFormat.NATIONAL));
- assertEquals("+44 20 8738 9353", phoneUtil.format(gbNumber, PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("(020) 7031 3000", phoneUtil.format(GB_NUMBER, PhoneNumberFormat.NATIONAL));
+ assertEquals("+44 20 7031 3000", phoneUtil.format(GB_NUMBER, PhoneNumberFormat.INTERNATIONAL));
- gbNumber.clear();
- gbNumber.setCountryCode(44).setNationalNumber(7912345678L);
- assertEquals("(07912) 345 678", phoneUtil.format(gbNumber, PhoneNumberFormat.NATIONAL));
- assertEquals("+44 7912 345 678", phoneUtil.format(gbNumber, PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("(07912) 345 678", phoneUtil.format(GB_MOBILE, PhoneNumberFormat.NATIONAL));
+ assertEquals("+44 7912 345 678", phoneUtil.format(GB_MOBILE, PhoneNumberFormat.INTERNATIONAL));
}
public void testFormatDENumber() {
@@ -335,159 +323,160 @@ public class PhoneNumberUtilTest extends TestCase {
assertEquals("+49 291 12345678", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));
deNumber.clear();
- deNumber.setCountryCode(49).setNationalNumber(9123123L);
- assertEquals("09123 123", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
- assertEquals("+49 9123 123", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));
+ deNumber.setCountryCode(49).setNationalNumber(912312345L);
+ assertEquals("09123 12345", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
+ assertEquals("+49 9123 12345", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));
deNumber.clear();
deNumber.setCountryCode(49).setNationalNumber(80212345L);
assertEquals("08021 2345", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
assertEquals("+49 8021 2345", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));
- deNumber.clear();
- deNumber.setCountryCode(49).setNationalNumber(1234L);
// Note this number is correctly formatted without national prefix. Most of the numbers that
// are treated as invalid numbers by the library are short numbers, and they are usually not
// dialed with national prefix.
- assertEquals("1234", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
- assertEquals("+49 1234", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("1234", phoneUtil.format(DE_SHORT_NUMBER, PhoneNumberFormat.NATIONAL));
+ assertEquals("+49 1234", phoneUtil.format(DE_SHORT_NUMBER, PhoneNumberFormat.INTERNATIONAL));
+
+ deNumber.setCountryCode(49).setNationalNumber(41341234);
+ assertEquals("04134 1234", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
}
public void testFormatITNumber() {
- PhoneNumber itNumber = new PhoneNumber();
- itNumber.setCountryCode(39).setNationalNumber(236618300L).setItalianLeadingZero(true);
- assertEquals("02 3661 8300", phoneUtil.format(itNumber, PhoneNumberFormat.NATIONAL));
- assertEquals("+39 02 3661 8300", phoneUtil.format(itNumber, PhoneNumberFormat.INTERNATIONAL));
- assertEquals("+390236618300", phoneUtil.format(itNumber, PhoneNumberFormat.E164));
+ assertEquals("02 3661 8300", phoneUtil.format(IT_NUMBER, PhoneNumberFormat.NATIONAL));
+ assertEquals("+39 02 3661 8300", phoneUtil.format(IT_NUMBER, PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("+390236618300", phoneUtil.format(IT_NUMBER, PhoneNumberFormat.E164));
- itNumber.clear();
- itNumber.setCountryCode(39).setNationalNumber(345678901L);
- assertEquals("345 678 901", phoneUtil.format(itNumber, PhoneNumberFormat.NATIONAL));
- assertEquals("+39 345 678 901", phoneUtil.format(itNumber, PhoneNumberFormat.INTERNATIONAL));
- assertEquals("+39345678901", phoneUtil.format(itNumber, PhoneNumberFormat.E164));
+ assertEquals("345 678 901", phoneUtil.format(IT_MOBILE, PhoneNumberFormat.NATIONAL));
+ assertEquals("+39 345 678 901", phoneUtil.format(IT_MOBILE, PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("+39345678901", phoneUtil.format(IT_MOBILE, PhoneNumberFormat.E164));
}
public void testFormatAUNumber() {
- PhoneNumber auNumber = new PhoneNumber();
- auNumber.setCountryCode(61).setNationalNumber(236618300L);
- assertEquals("02 3661 8300", phoneUtil.format(auNumber, PhoneNumberFormat.NATIONAL));
- assertEquals("+61 2 3661 8300", phoneUtil.format(auNumber, PhoneNumberFormat.INTERNATIONAL));
- assertEquals("+61236618300", phoneUtil.format(auNumber, PhoneNumberFormat.E164));
-
- auNumber.clear();
- auNumber.setCountryCode(61).setNationalNumber(1800123456L);
+ assertEquals("02 3661 8300", phoneUtil.format(AU_NUMBER, PhoneNumberFormat.NATIONAL));
+ assertEquals("+61 2 3661 8300", phoneUtil.format(AU_NUMBER, PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("+61236618300", phoneUtil.format(AU_NUMBER, PhoneNumberFormat.E164));
+
+ PhoneNumber auNumber = new PhoneNumber().setCountryCode(61).setNationalNumber(1800123456L);
assertEquals("1800 123 456", phoneUtil.format(auNumber, PhoneNumberFormat.NATIONAL));
assertEquals("+61 1800 123 456", phoneUtil.format(auNumber, PhoneNumberFormat.INTERNATIONAL));
assertEquals("+611800123456", phoneUtil.format(auNumber, PhoneNumberFormat.E164));
}
public void testFormatARNumber() {
- PhoneNumber arNumber = new PhoneNumber();
- arNumber.setCountryCode(54).setNationalNumber(1187654321L);
- assertEquals("011 8765-4321", phoneUtil.format(arNumber, PhoneNumberFormat.NATIONAL));
- assertEquals("+54 11 8765-4321", phoneUtil.format(arNumber, PhoneNumberFormat.INTERNATIONAL));
- assertEquals("+541187654321", phoneUtil.format(arNumber, PhoneNumberFormat.E164));
+ assertEquals("011 8765-4321", phoneUtil.format(AR_NUMBER, PhoneNumberFormat.NATIONAL));
+ assertEquals("+54 11 8765-4321", phoneUtil.format(AR_NUMBER, PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("+541187654321", phoneUtil.format(AR_NUMBER, PhoneNumberFormat.E164));
- arNumber.clear();
- arNumber.setCountryCode(54).setNationalNumber(91187654321L);
- assertEquals("011 15 8765-4321", phoneUtil.format(arNumber, PhoneNumberFormat.NATIONAL));
- assertEquals("+54 9 11 8765 4321", phoneUtil.format(arNumber, PhoneNumberFormat.INTERNATIONAL));
- assertEquals("+5491187654321", phoneUtil.format(arNumber, PhoneNumberFormat.E164));
+ assertEquals("011 15 8765-4321", phoneUtil.format(AR_MOBILE, PhoneNumberFormat.NATIONAL));
+ assertEquals("+54 9 11 8765 4321", phoneUtil.format(AR_MOBILE,
+ PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("+5491187654321", phoneUtil.format(AR_MOBILE, PhoneNumberFormat.E164));
}
public void testFormatOutOfCountryCallingNumber() {
- PhoneNumber usNumber = new PhoneNumber();
- usNumber.setCountryCode(1).setNationalNumber(9002530000L);
assertEquals("00 1 900 253 0000",
- phoneUtil.formatOutOfCountryCallingNumber(usNumber, "DE"));
+ phoneUtil.formatOutOfCountryCallingNumber(US_PREMIUM, "DE"));
- usNumber.clear();
- usNumber.setCountryCode(1).setNationalNumber(6502530000L);
assertEquals("1 650 253 0000",
- phoneUtil.formatOutOfCountryCallingNumber(usNumber, "BS"));
+ phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER, "BS"));
assertEquals("0~0 1 650 253 0000",
- phoneUtil.formatOutOfCountryCallingNumber(usNumber, "PL"));
+ phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER, "PL"));
- PhoneNumber gbNumber = new PhoneNumber();
- gbNumber.setCountryCode(44).setNationalNumber(7912345678L);
assertEquals("011 44 7912 345 678",
- phoneUtil.formatOutOfCountryCallingNumber(gbNumber, "US"));
+ phoneUtil.formatOutOfCountryCallingNumber(GB_MOBILE, "US"));
- PhoneNumber deNumber = new PhoneNumber();
- deNumber.setCountryCode(49).setNationalNumber(1234L);
assertEquals("00 49 1234",
- phoneUtil.formatOutOfCountryCallingNumber(deNumber, "GB"));
+ phoneUtil.formatOutOfCountryCallingNumber(DE_SHORT_NUMBER, "GB"));
// Note this number is correctly formatted without national prefix. Most of the numbers that
// are treated as invalid numbers by the library are short numbers, and they are usually not
// dialed with national prefix.
- assertEquals("1234",
- phoneUtil.formatOutOfCountryCallingNumber(deNumber, "DE"));
+ assertEquals("1234", phoneUtil.formatOutOfCountryCallingNumber(DE_SHORT_NUMBER, "DE"));
- PhoneNumber itNumber = new PhoneNumber();
- itNumber.setCountryCode(39).setNationalNumber(236618300L).setItalianLeadingZero(true);
assertEquals("011 39 02 3661 8300",
- phoneUtil.formatOutOfCountryCallingNumber(itNumber, "US"));
+ phoneUtil.formatOutOfCountryCallingNumber(IT_NUMBER, "US"));
assertEquals("02 3661 8300",
- phoneUtil.formatOutOfCountryCallingNumber(itNumber, "IT"));
+ phoneUtil.formatOutOfCountryCallingNumber(IT_NUMBER, "IT"));
assertEquals("+39 02 3661 8300",
- phoneUtil.formatOutOfCountryCallingNumber(itNumber, "SG"));
+ phoneUtil.formatOutOfCountryCallingNumber(IT_NUMBER, "SG"));
- PhoneNumber sgNumber = new PhoneNumber();
- sgNumber.setCountryCode(65).setNationalNumber(94777892L);
- assertEquals("9477 7892",
- phoneUtil.formatOutOfCountryCallingNumber(sgNumber, "SG"));
+ assertEquals("6521 8000",
+ phoneUtil.formatOutOfCountryCallingNumber(SG_NUMBER, "SG"));
- PhoneNumber arNumber = new PhoneNumber();
- arNumber.setCountryCode(54).setNationalNumber(91187654321L);
assertEquals("011 54 9 11 8765 4321",
- phoneUtil.formatOutOfCountryCallingNumber(arNumber, "US"));
+ phoneUtil.formatOutOfCountryCallingNumber(AR_MOBILE, "US"));
- arNumber.setExtension("1234");
+ PhoneNumber arNumberWithExtn = new PhoneNumber().mergeFrom(AR_MOBILE).setExtension("1234");
assertEquals("011 54 9 11 8765 4321 ext. 1234",
- phoneUtil.formatOutOfCountryCallingNumber(arNumber, "US"));
+ phoneUtil.formatOutOfCountryCallingNumber(arNumberWithExtn, "US"));
assertEquals("0011 54 9 11 8765 4321 ext. 1234",
- phoneUtil.formatOutOfCountryCallingNumber(arNumber, "AU"));
+ phoneUtil.formatOutOfCountryCallingNumber(arNumberWithExtn, "AU"));
assertEquals("011 15 8765-4321 ext. 1234",
- phoneUtil.formatOutOfCountryCallingNumber(arNumber, "AR"));
+ phoneUtil.formatOutOfCountryCallingNumber(arNumberWithExtn, "AR"));
}
public void testFormatOutOfCountryWithPreferredIntlPrefix() {
- PhoneNumber itNumber = new PhoneNumber();
- itNumber.setCountryCode(39).setNationalNumber(236618300L).setItalianLeadingZero(true);
// This should use 0011, since that is the preferred international prefix (both 0011 and 0012
// are accepted as possible international prefixes in our test metadta.)
assertEquals("0011 39 02 3661 8300",
- phoneUtil.formatOutOfCountryCallingNumber(itNumber, "AU"));
+ phoneUtil.formatOutOfCountryCallingNumber(IT_NUMBER, "AU"));
}
public void testFormatWithCarrierCode() {
+ // We only support this for AR in our test metadata, and only for mobile numbers starting with
+ // certain values.
+ PhoneNumber arMobile = new PhoneNumber().setCountryCode(54).setNationalNumber(92234654321L);
+ assertEquals("02234 65-4321", phoneUtil.format(arMobile, PhoneNumberFormat.NATIONAL));
+ // Here we force 14 as the carrier code.
+ assertEquals("02234 14 65-4321",
+ phoneUtil.formatNationalNumberWithCarrierCode(arMobile, "14"));
+ // Here we force the number to be shown with no carrier code.
+ assertEquals("02234 65-4321",
+ phoneUtil.formatNationalNumberWithCarrierCode(arMobile, ""));
+ // Here the international rule is used, so no carrier code should be present.
+ assertEquals("+5492234654321", phoneUtil.format(arMobile, PhoneNumberFormat.E164));
+ // We don't support this for the US so there should be no change.
+ assertEquals("650 253 0000", phoneUtil.formatNationalNumberWithCarrierCode(US_NUMBER, "15"));
+ }
+
+ public void testFormatWithPreferredCarrierCode() {
// We only support this for AR in our test metadata.
PhoneNumber arNumber = new PhoneNumber();
arNumber.setCountryCode(54).setNationalNumber(91234125678L);
+ // Test formatting with no preferred carrier code stored in the number itself.
+ assertEquals("01234 15 12-5678",
+ phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, "15"));
+ assertEquals("01234 12-5678",
+ phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, ""));
+ // Test formatting with preferred carrier code present.
+ arNumber.setPreferredDomesticCarrierCode("19");
assertEquals("01234 12-5678", phoneUtil.format(arNumber, PhoneNumberFormat.NATIONAL));
- // Test formatting with a carrier code.
- assertEquals("01234 15 12-5678", phoneUtil.formatNationalNumberWithCarrierCode(arNumber, "15"));
- // Here the international rule is used, so no carrier code should be present.
- assertEquals("+5491234125678", phoneUtil.format(arNumber, PhoneNumberFormat.E164));
+ assertEquals("01234 19 12-5678",
+ phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, "15"));
+ assertEquals("01234 19 12-5678",
+ phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, ""));
+ // When the preferred_domestic_carrier_code is present (even when it contains an empty string),
+ // use it instead of the default carrier code passed in.
+ arNumber.setPreferredDomesticCarrierCode("");
+ assertEquals("01234 12-5678",
+ phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, "15"));
// We don't support this for the US so there should be no change.
PhoneNumber usNumber = new PhoneNumber();
- usNumber.setCountryCode(1).setNationalNumber(4241231234L);
+ usNumber.setCountryCode(1).setNationalNumber(4241231234L).setPreferredDomesticCarrierCode("99");
assertEquals("424 123 1234", phoneUtil.format(usNumber, PhoneNumberFormat.NATIONAL));
- assertEquals("424 123 1234", phoneUtil.formatNationalNumberWithCarrierCode(usNumber, "15"));
+ assertEquals("424 123 1234",
+ phoneUtil.formatNationalNumberWithPreferredCarrierCode(usNumber, "15"));
}
public void testFormatByPattern() {
- PhoneNumber usNumber = new PhoneNumber();
- usNumber.setCountryCode(1).setNationalNumber(6502530000L);
-
NumberFormat newNumFormat = new NumberFormat();
newNumFormat.setPattern("(\\d{3})(\\d{3})(\\d{4})");
newNumFormat.setFormat("($1) $2-$3");
List newNumberFormats = new ArrayList();
newNumberFormats.add(newNumFormat);
- assertEquals("(650) 253-0000", phoneUtil.formatByPattern(usNumber, PhoneNumberFormat.NATIONAL,
+ assertEquals("(650) 253-0000", phoneUtil.formatByPattern(US_NUMBER, PhoneNumberFormat.NATIONAL,
newNumberFormats));
- assertEquals("+1 (650) 253-0000", phoneUtil.formatByPattern(usNumber,
+ assertEquals("+1 (650) 253-0000", phoneUtil.formatByPattern(US_NUMBER,
PhoneNumberFormat.INTERNATIONAL,
newNumberFormats));
@@ -495,69 +484,60 @@ public class PhoneNumberUtilTest extends TestCase {
// followed.
newNumFormat.setNationalPrefixFormattingRule("$NP ($FG)");
newNumFormat.setFormat("$1 $2-$3");
- PhoneNumber bsNumber = new PhoneNumber();
- bsNumber.setCountryCode(1).setNationalNumber(4168819999L);
- assertEquals("1 (416) 881-9999",
- phoneUtil.formatByPattern(bsNumber, PhoneNumberFormat.NATIONAL, newNumberFormats));
- assertEquals("+1 416 881-9999",
- phoneUtil.formatByPattern(bsNumber, PhoneNumberFormat.INTERNATIONAL,
+ assertEquals("1 (242) 365-1234",
+ phoneUtil.formatByPattern(BS_NUMBER, PhoneNumberFormat.NATIONAL,
+ newNumberFormats));
+ assertEquals("+1 242 365-1234",
+ phoneUtil.formatByPattern(BS_NUMBER, PhoneNumberFormat.INTERNATIONAL,
newNumberFormats));
-
- PhoneNumber itNumber = new PhoneNumber();
- itNumber.setCountryCode(39).setNationalNumber(236618300L).setItalianLeadingZero(true);
newNumFormat.setPattern("(\\d{2})(\\d{5})(\\d{3})");
newNumFormat.setFormat("$1-$2 $3");
newNumberFormats.set(0, newNumFormat);
assertEquals("02-36618 300",
- phoneUtil.formatByPattern(itNumber, PhoneNumberFormat.NATIONAL, newNumberFormats));
+ phoneUtil.formatByPattern(IT_NUMBER, PhoneNumberFormat.NATIONAL,
+ newNumberFormats));
assertEquals("+39 02-36618 300",
- phoneUtil.formatByPattern(itNumber, PhoneNumberFormat.INTERNATIONAL,
+ phoneUtil.formatByPattern(IT_NUMBER, PhoneNumberFormat.INTERNATIONAL,
newNumberFormats));
- PhoneNumber gbNumber = new PhoneNumber();
- gbNumber.setCountryCode(44).setNationalNumber(2012345678L);
-
newNumFormat.setNationalPrefixFormattingRule("$NP$FG");
newNumFormat.setPattern("(\\d{2})(\\d{4})(\\d{4})");
newNumFormat.setFormat("$1 $2 $3");
newNumberFormats.set(0, newNumFormat);
- assertEquals("020 1234 5678",
- phoneUtil.formatByPattern(gbNumber, PhoneNumberFormat.NATIONAL, newNumberFormats));
+ assertEquals("020 7031 3000",
+ phoneUtil.formatByPattern(GB_NUMBER, PhoneNumberFormat.NATIONAL,
+ newNumberFormats));
newNumFormat.setNationalPrefixFormattingRule("($NP$FG)");
- assertEquals("(020) 1234 5678",
- phoneUtil.formatByPattern(gbNumber, PhoneNumberFormat.NATIONAL, newNumberFormats));
+ assertEquals("(020) 7031 3000",
+ phoneUtil.formatByPattern(GB_NUMBER, PhoneNumberFormat.NATIONAL,
+ newNumberFormats));
newNumFormat.setNationalPrefixFormattingRule("");
- assertEquals("20 1234 5678",
- phoneUtil.formatByPattern(gbNumber, PhoneNumberFormat.NATIONAL, newNumberFormats));
+ assertEquals("20 7031 3000",
+ phoneUtil.formatByPattern(GB_NUMBER, PhoneNumberFormat.NATIONAL,
+ newNumberFormats));
- newNumFormat.setNationalPrefixFormattingRule("");
- assertEquals("+44 20 1234 5678",
- phoneUtil.formatByPattern(gbNumber, PhoneNumberFormat.INTERNATIONAL,
+ assertEquals("+44 20 7031 3000",
+ phoneUtil.formatByPattern(GB_NUMBER, PhoneNumberFormat.INTERNATIONAL,
newNumberFormats));
}
public void testFormatE164Number() {
- PhoneNumber usNumber = new PhoneNumber();
- usNumber.setCountryCode(1).setNationalNumber(6502530000L);
- assertEquals("+16502530000", phoneUtil.format(usNumber, PhoneNumberFormat.E164));
- PhoneNumber deNumber = new PhoneNumber();
- deNumber.setCountryCode(49).setNationalNumber(301234L);
- assertEquals("+49301234", phoneUtil.format(deNumber, PhoneNumberFormat.E164));
+ assertEquals("+16502530000", phoneUtil.format(US_NUMBER, PhoneNumberFormat.E164));
+ assertEquals("+4930123456", phoneUtil.format(DE_NUMBER, PhoneNumberFormat.E164));
}
public void testFormatNumberWithExtension() {
- PhoneNumber nzNumber = new PhoneNumber();
- nzNumber.setCountryCode(64).setNationalNumber(33316005L).setExtension("1234");
+ PhoneNumber nzNumber = new PhoneNumber().mergeFrom(NZ_NUMBER).setExtension("1234");
// Uses default extension prefix:
assertEquals("03-331 6005 ext. 1234", phoneUtil.format(nzNumber, PhoneNumberFormat.NATIONAL));
// Extension prefix overridden in the territory information for the US:
- PhoneNumber usNumber = new PhoneNumber();
- usNumber.setCountryCode(1).setNationalNumber(6502530000L).setExtension("4567");
- assertEquals("650 253 0000 extn. 4567", phoneUtil.format(usNumber, PhoneNumberFormat.NATIONAL));
+ PhoneNumber usNumberWithExtension = new PhoneNumber().mergeFrom(US_NUMBER).setExtension("4567");
+ assertEquals("650 253 0000 extn. 4567", phoneUtil.format(usNumberWithExtension,
+ PhoneNumberFormat.NATIONAL));
}
public void testFormatUsingOriginalNumberFormat() throws Exception {
@@ -578,13 +558,9 @@ public class PhoneNumberUtilTest extends TestCase {
}
public void testIsPremiumRate() {
- PhoneNumber premiumRateNumber = new PhoneNumber();
-
- premiumRateNumber.setCountryCode(1).setNationalNumber(9004433030L);
- assertEquals(PhoneNumberUtil.PhoneNumberType.PREMIUM_RATE,
- phoneUtil.getNumberType(premiumRateNumber));
+ assertEquals(PhoneNumberUtil.PhoneNumberType.PREMIUM_RATE, phoneUtil.getNumberType(US_PREMIUM));
- premiumRateNumber.clear();
+ PhoneNumber premiumRateNumber = new PhoneNumber();
premiumRateNumber.setCountryCode(39).setNationalNumber(892123L);
assertEquals(PhoneNumberUtil.PhoneNumberType.PREMIUM_RATE,
phoneUtil.getNumberType(premiumRateNumber));
@@ -629,67 +605,30 @@ public class PhoneNumberUtilTest extends TestCase {
}
public void testIsMobile() {
- PhoneNumber mobileNumber = new PhoneNumber();
-
- // A Bahama mobile number
- mobileNumber.setCountryCode(1).setNationalNumber(2423570000L);
- assertEquals(PhoneNumberUtil.PhoneNumberType.MOBILE,
- phoneUtil.getNumberType(mobileNumber));
-
- mobileNumber.clear();
- mobileNumber.setCountryCode(39).setNationalNumber(312345678L);
- assertEquals(PhoneNumberUtil.PhoneNumberType.MOBILE,
- phoneUtil.getNumberType(mobileNumber));
+ assertEquals(PhoneNumberUtil.PhoneNumberType.MOBILE, phoneUtil.getNumberType(BS_MOBILE));
+ assertEquals(PhoneNumberUtil.PhoneNumberType.MOBILE, phoneUtil.getNumberType(GB_MOBILE));
+ assertEquals(PhoneNumberUtil.PhoneNumberType.MOBILE, phoneUtil.getNumberType(IT_MOBILE));
- mobileNumber.clear();
- mobileNumber.setCountryCode(44).setNationalNumber(7912345678L);
- assertEquals(PhoneNumberUtil.PhoneNumberType.MOBILE,
- phoneUtil.getNumberType(mobileNumber));
-
- mobileNumber.clear();
+ PhoneNumber mobileNumber = new PhoneNumber();
mobileNumber.setCountryCode(49).setNationalNumber(15123456789L);
- assertEquals(PhoneNumberUtil.PhoneNumberType.MOBILE,
- phoneUtil.getNumberType(mobileNumber));
+ assertEquals(PhoneNumberUtil.PhoneNumberType.MOBILE, phoneUtil.getNumberType(mobileNumber));
- mobileNumber.clear();
- mobileNumber.setCountryCode(54).setNationalNumber(91187654321L);
- assertEquals(PhoneNumberUtil.PhoneNumberType.MOBILE,
- phoneUtil.getNumberType(mobileNumber));
+ assertEquals(PhoneNumberUtil.PhoneNumberType.MOBILE, phoneUtil.getNumberType(AR_MOBILE));
}
public void testIsFixedLine() {
- PhoneNumber fixedLineNumber = new PhoneNumber();
-
- // A Bahama fixed-line number
- fixedLineNumber.setCountryCode(1).setNationalNumber(2423651234L);
- assertEquals(PhoneNumberUtil.PhoneNumberType.FIXED_LINE,
- phoneUtil.getNumberType(fixedLineNumber));
-
- // An Italian fixed-line number
- fixedLineNumber.clear();
- fixedLineNumber.setCountryCode(39).setNationalNumber(236618300L).setItalianLeadingZero(true);
- assertEquals(PhoneNumberUtil.PhoneNumberType.FIXED_LINE,
- phoneUtil.getNumberType(fixedLineNumber));
-
- fixedLineNumber.clear();
- fixedLineNumber.setCountryCode(44).setNationalNumber(2012345678L);
- assertEquals(PhoneNumberUtil.PhoneNumberType.FIXED_LINE,
- phoneUtil.getNumberType(fixedLineNumber));
-
- fixedLineNumber.clear();
- fixedLineNumber.setCountryCode(49).setNationalNumber(301234L);
- assertEquals(PhoneNumberUtil.PhoneNumberType.FIXED_LINE,
- phoneUtil.getNumberType(fixedLineNumber));
+ assertEquals(PhoneNumberUtil.PhoneNumberType.FIXED_LINE, phoneUtil.getNumberType(BS_NUMBER));
+ assertEquals(PhoneNumberUtil.PhoneNumberType.FIXED_LINE, phoneUtil.getNumberType(IT_NUMBER));
+ assertEquals(PhoneNumberUtil.PhoneNumberType.FIXED_LINE, phoneUtil.getNumberType(GB_NUMBER));
+ assertEquals(PhoneNumberUtil.PhoneNumberType.FIXED_LINE, phoneUtil.getNumberType(DE_NUMBER));
}
public void testIsFixedLineAndMobile() {
- PhoneNumber fixedLineAndMobileNumber = new PhoneNumber();
- fixedLineAndMobileNumber.setCountryCode(1).setNationalNumber(6502531111L);
assertEquals(PhoneNumberUtil.PhoneNumberType.FIXED_LINE_OR_MOBILE,
- phoneUtil.getNumberType(fixedLineAndMobileNumber));
+ phoneUtil.getNumberType(US_NUMBER));
- fixedLineAndMobileNumber.clear();
- fixedLineAndMobileNumber.setCountryCode(54).setNationalNumber(1987654321L);
+ PhoneNumber fixedLineAndMobileNumber = new PhoneNumber().
+ setCountryCode(54).setNationalNumber(1987654321L);
assertEquals(PhoneNumberUtil.PhoneNumberType.FIXED_LINE_OR_MOBILE,
phoneUtil.getNumberType(fixedLineAndMobileNumber));
}
@@ -714,41 +653,29 @@ public class PhoneNumberUtilTest extends TestCase {
}
public void testIsUnknown() {
- PhoneNumber unknownNumber = new PhoneNumber();
- unknownNumber.setCountryCode(1).setNationalNumber(65025311111L);
- assertEquals(PhoneNumberUtil.PhoneNumberType.UNKNOWN,
- phoneUtil.getNumberType(unknownNumber));
+ // Invalid numbers should be of type UNKNOWN.
+ assertEquals(PhoneNumberUtil.PhoneNumberType.UNKNOWN, phoneUtil.getNumberType(US_LOCAL_NUMBER));
}
public void testIsValidNumber() {
- PhoneNumber usNumber = new PhoneNumber();
- usNumber.setCountryCode(1).setNationalNumber(6502530000L);
- assertTrue(phoneUtil.isValidNumber(usNumber));
+ assertTrue(phoneUtil.isValidNumber(US_NUMBER));
+ assertTrue(phoneUtil.isValidNumber(IT_NUMBER));
+ assertTrue(phoneUtil.isValidNumber(GB_MOBILE));
- PhoneNumber itNumber = new PhoneNumber();
- itNumber.setCountryCode(39).setNationalNumber(236618300L).setItalianLeadingZero(true);
- assertTrue(phoneUtil.isValidNumber(itNumber));
-
- PhoneNumber gbNumber = new PhoneNumber();
- gbNumber.setCountryCode(44).setNationalNumber(7912345678L);
- assertTrue(phoneUtil.isValidNumber(gbNumber));
-
- PhoneNumber nzNumber = new PhoneNumber();
- nzNumber.setCountryCode(64).setNationalNumber(21387835L);
+ PhoneNumber nzNumber = new PhoneNumber().setCountryCode(64).setNationalNumber(21387835L);
assertTrue(phoneUtil.isValidNumber(nzNumber));
}
public void testIsValidForRegion() {
// This number is valid for the Bahamas, but is not a valid US number.
- PhoneNumber bsNumber = new PhoneNumber();
- bsNumber.setCountryCode(1).setNationalNumber(2423232345L);
- assertTrue(phoneUtil.isValidNumber(bsNumber));
- assertTrue(phoneUtil.isValidNumberForRegion(bsNumber, "BS"));
- assertTrue(phoneUtil.isValidNumberForRegion(bsNumber, "bs"));
- assertFalse(phoneUtil.isValidNumberForRegion(bsNumber, "US"));
- bsNumber.setNationalNumber(2421232345L);
+ assertTrue(phoneUtil.isValidNumber(BS_NUMBER));
+ assertTrue(phoneUtil.isValidNumberForRegion(BS_NUMBER, "BS"));
+ assertTrue(phoneUtil.isValidNumberForRegion(BS_NUMBER, "bs"));
+ assertFalse(phoneUtil.isValidNumberForRegion(BS_NUMBER, "US"));
+ PhoneNumber bsInvalidNumber =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(2421232345L);
// This number is no longer valid.
- assertFalse(phoneUtil.isValidNumber(bsNumber));
+ assertFalse(phoneUtil.isValidNumber(bsInvalidNumber));
// La Mayotte and Reunion use 'leadingDigits' to differentiate them.
PhoneNumber reNumber = new PhoneNumber();
@@ -774,25 +701,23 @@ public class PhoneNumberUtilTest extends TestCase {
}
public void testIsNotValidNumber() {
- PhoneNumber usNumber = new PhoneNumber();
- usNumber.setCountryCode(1).setNationalNumber(2530000L);
- assertFalse(phoneUtil.isValidNumber(usNumber));
+ assertFalse(phoneUtil.isValidNumber(US_LOCAL_NUMBER));
- PhoneNumber itNumber = new PhoneNumber();
- itNumber.setCountryCode(39).setNationalNumber(23661830000L).setItalianLeadingZero(true);
- assertFalse(phoneUtil.isValidNumber(itNumber));
+ PhoneNumber invalidNumber = new PhoneNumber();
+ invalidNumber.setCountryCode(39).setNationalNumber(23661830000L).setItalianLeadingZero(true);
+ assertFalse(phoneUtil.isValidNumber(invalidNumber));
- PhoneNumber gbNumber = new PhoneNumber();
- gbNumber.setCountryCode(44).setNationalNumber(791234567L);
- assertFalse(phoneUtil.isValidNumber(gbNumber));
+ invalidNumber.clear();
+ invalidNumber.setCountryCode(44).setNationalNumber(791234567L);
+ assertFalse(phoneUtil.isValidNumber(invalidNumber));
- PhoneNumber deNumber = new PhoneNumber();
- deNumber.setCountryCode(49).setNationalNumber(1234L);
- assertFalse(phoneUtil.isValidNumber(deNumber));
+ invalidNumber.clear();
+ invalidNumber.setCountryCode(49).setNationalNumber(1234L);
+ assertFalse(phoneUtil.isValidNumber(invalidNumber));
- PhoneNumber nzNumber = new PhoneNumber();
- nzNumber.setCountryCode(64).setNationalNumber(3316005L);
- assertFalse(phoneUtil.isValidNumber(nzNumber));
+ invalidNumber.clear();
+ invalidNumber.setCountryCode(64).setNationalNumber(3316005L);
+ assertFalse(phoneUtil.isValidNumber(invalidNumber));
}
public void testGetRegionCodeForCountryCode() {
@@ -802,17 +727,9 @@ public class PhoneNumberUtilTest extends TestCase {
}
public void testGetRegionCodeForNumber() {
- PhoneNumber bsNumber = new PhoneNumber();
- bsNumber.setCountryCode(1).setNationalNumber(2423027000L);
- assertEquals("BS", phoneUtil.getRegionCodeForNumber(bsNumber));
-
- PhoneNumber usNumber = new PhoneNumber();
- usNumber.setCountryCode(1).setNationalNumber(6502530000L);
- assertEquals("US", phoneUtil.getRegionCodeForNumber(usNumber));
-
- PhoneNumber gbNumber = new PhoneNumber();
- gbNumber.setCountryCode(44).setNationalNumber(7912345678L);
- assertEquals("GB", phoneUtil.getRegionCodeForNumber(gbNumber));
+ assertEquals("BS", phoneUtil.getRegionCodeForNumber(BS_NUMBER));
+ assertEquals("US", phoneUtil.getRegionCodeForNumber(US_NUMBER));
+ assertEquals("GB", phoneUtil.getRegionCodeForNumber(GB_MOBILE));
}
public void testGetCountryCodeForRegion() {
@@ -848,17 +765,9 @@ public class PhoneNumberUtilTest extends TestCase {
}
public void testIsPossibleNumber() {
- PhoneNumber number = new PhoneNumber();
- number.setCountryCode(1).setNationalNumber(6502530000L);
- assertTrue(phoneUtil.isPossibleNumber(number));
-
- number.clear();
- number.setCountryCode(1).setNationalNumber(2530000L);
- assertTrue(phoneUtil.isPossibleNumber(number));
-
- number.clear();
- number.setCountryCode(44).setNationalNumber(2070313000L);
- assertTrue(phoneUtil.isPossibleNumber(number));
+ assertTrue(phoneUtil.isPossibleNumber(US_NUMBER));
+ assertTrue(phoneUtil.isPossibleNumber(US_LOCAL_NUMBER));
+ assertTrue(phoneUtil.isPossibleNumber(GB_NUMBER));
assertTrue(phoneUtil.isPossibleNumber("+1 650 253 0000", "US"));
assertTrue(phoneUtil.isPossibleNumber("+1 650 GOO OGLE", "US"));
@@ -874,17 +783,16 @@ public class PhoneNumberUtilTest extends TestCase {
public void testIsPossibleNumberWithReason() {
// FYI, national numbers for country code +1 that are within 7 to 10 digits are possible.
- PhoneNumber number = new PhoneNumber();
- number.setCountryCode(1).setNationalNumber(6502530000L);
assertEquals(PhoneNumberUtil.ValidationResult.IS_POSSIBLE,
- phoneUtil.isPossibleNumberWithReason(number));
+ phoneUtil.isPossibleNumberWithReason(US_NUMBER));
- number.clear();
- number.setCountryCode(1).setNationalNumber(2530000L);
assertEquals(PhoneNumberUtil.ValidationResult.IS_POSSIBLE,
- phoneUtil.isPossibleNumberWithReason(number));
+ phoneUtil.isPossibleNumberWithReason(US_LOCAL_NUMBER));
- number.clear();
+ assertEquals(PhoneNumberUtil.ValidationResult.TOO_LONG,
+ phoneUtil.isPossibleNumberWithReason(US_LONG_NUMBER));
+
+ PhoneNumber number = new PhoneNumber();
number.setCountryCode(0).setNationalNumber(2530000L);
assertEquals(PhoneNumberUtil.ValidationResult.INVALID_COUNTRY_CODE,
phoneUtil.isPossibleNumberWithReason(number));
@@ -894,11 +802,6 @@ public class PhoneNumberUtilTest extends TestCase {
assertEquals(PhoneNumberUtil.ValidationResult.TOO_SHORT,
phoneUtil.isPossibleNumberWithReason(number));
- number.clear();
- number.setCountryCode(1).setNationalNumber(65025300000L);
- assertEquals(PhoneNumberUtil.ValidationResult.TOO_LONG,
- phoneUtil.isPossibleNumberWithReason(number));
-
// Try with number that we don't have metadata for.
PhoneNumber adNumber = new PhoneNumber();
adNumber.setCountryCode(376).setNationalNumber(12345L);
@@ -913,11 +816,9 @@ public class PhoneNumberUtilTest extends TestCase {
}
public void testIsNotPossibleNumber() {
- PhoneNumber number = new PhoneNumber();
- number.setCountryCode(1).setNationalNumber(65025300000L);
- assertFalse(phoneUtil.isPossibleNumber(number));
+ assertFalse(phoneUtil.isPossibleNumber(US_LONG_NUMBER));
- number.clear();
+ PhoneNumber number = new PhoneNumber();
number.setCountryCode(1).setNationalNumber(253000L);
assertFalse(phoneUtil.isPossibleNumber(number));
@@ -935,17 +836,13 @@ public class PhoneNumberUtilTest extends TestCase {
public void testTruncateTooLongNumber() {
// US number 650-253-0000, but entered with one additional digit at the end.
- PhoneNumber tooLongNumber = new PhoneNumber();
- tooLongNumber.setCountryCode(1).setNationalNumber(65025300001L);
- PhoneNumber validNumber = new PhoneNumber();
- validNumber.setCountryCode(1).setNationalNumber(6502530000L);
- assertTrue(phoneUtil.truncateTooLongNumber(tooLongNumber));
- assertEquals(validNumber, tooLongNumber);
+ assertTrue(phoneUtil.truncateTooLongNumber(US_LONG_NUMBER));
+ assertEquals(US_NUMBER, US_LONG_NUMBER);
// GB number 080 1234 5678, but entered with 4 extra digits at the end.
- tooLongNumber.clear();
+ PhoneNumber tooLongNumber = new PhoneNumber();
tooLongNumber.setCountryCode(44).setNationalNumber(80123456780123L);
- validNumber.clear();
+ PhoneNumber validNumber = new PhoneNumber();
validNumber.setCountryCode(44).setNationalNumber(8012345678L);
assertTrue(phoneUtil.truncateTooLongNumber(tooLongNumber));
assertEquals(validNumber, tooLongNumber);
@@ -959,8 +856,7 @@ public class PhoneNumberUtilTest extends TestCase {
assertEquals(validNumber, tooLongNumber);
// Tests what happens when a valid number is passed in.
- PhoneNumber validNumberCopy = new PhoneNumber();
- validNumberCopy.mergeFrom(validNumber);
+ PhoneNumber validNumberCopy = new PhoneNumber().mergeFrom(validNumber);
assertTrue(phoneUtil.truncateTooLongNumber(validNumber));
// Tests the number is not modified.
assertEquals(validNumberCopy, validNumber);
@@ -969,17 +865,14 @@ public class PhoneNumberUtilTest extends TestCase {
PhoneNumber numberWithInvalidPrefix = new PhoneNumber();
// The test metadata says US numbers cannot have prefix 240.
numberWithInvalidPrefix.setCountryCode(1).setNationalNumber(2401234567L);
- PhoneNumber invalidNumberCopy = new PhoneNumber();
- invalidNumberCopy.mergeFrom(numberWithInvalidPrefix);
+ PhoneNumber invalidNumberCopy = new PhoneNumber().mergeFrom(numberWithInvalidPrefix);
assertFalse(phoneUtil.truncateTooLongNumber(numberWithInvalidPrefix));
// Tests the number is not modified.
assertEquals(invalidNumberCopy, numberWithInvalidPrefix);
// Tests what happens when a too short number is passed in.
- PhoneNumber tooShortNumber = new PhoneNumber();
- tooShortNumber.setCountryCode(1).setNationalNumber(1234L);
- PhoneNumber tooShortNumberCopy = new PhoneNumber();
- tooShortNumberCopy.mergeFrom(tooShortNumber);
+ PhoneNumber tooShortNumber = new PhoneNumber().setCountryCode(1).setNationalNumber(1234L);
+ PhoneNumber tooShortNumberCopy = new PhoneNumber().mergeFrom(tooShortNumber);
assertFalse(phoneUtil.truncateTooLongNumber(tooShortNumber));
// Tests the number is not modified.
assertEquals(tooShortNumberCopy, tooShortNumber);
@@ -1030,32 +923,48 @@ public class PhoneNumberUtilTest extends TestCase {
}
public void testMaybeStripNationalPrefix() {
- String nationalPrefix = "34";
+ PhoneMetadata metadata = new PhoneMetadata();
+ metadata.setNationalPrefixForParsing("34");
+ metadata.setGeneralDesc(new PhoneNumberDesc().setNationalNumberPattern("\\d{4,8}"));
StringBuffer numberToStrip = new StringBuffer("34356778");
String strippedNumber = "356778";
- String nationalRuleRegExp = "\\d{4,7}";
- Pattern nationalRule = Pattern.compile(nationalRuleRegExp);
- phoneUtil.maybeStripNationalPrefix(numberToStrip, nationalPrefix, "", nationalRule);
+ phoneUtil.maybeStripNationalPrefixAndCarrierCode(numberToStrip, metadata);
assertEquals("Should have had national prefix stripped.",
strippedNumber, numberToStrip.toString());
// Retry stripping - now the number should not start with the national prefix, so no more
// stripping should occur.
- phoneUtil.maybeStripNationalPrefix(numberToStrip, nationalPrefix, "", nationalRule);
+ phoneUtil.maybeStripNationalPrefixAndCarrierCode(numberToStrip, metadata);
assertEquals("Should have had no change - no national prefix present.",
strippedNumber, numberToStrip.toString());
// Some countries have no national prefix. Repeat test with none specified.
- nationalPrefix = "";
- phoneUtil.maybeStripNationalPrefix(numberToStrip, nationalPrefix, "", nationalRule);
+ metadata.setNationalPrefixForParsing("");
+ phoneUtil.maybeStripNationalPrefixAndCarrierCode(numberToStrip, metadata);
assertEquals("Should not strip anything with empty national prefix.",
strippedNumber, numberToStrip.toString());
// If the resultant number doesn't match the national rule, it shouldn't be stripped.
- nationalPrefix = "3";
+ metadata.setNationalPrefixForParsing("3");
numberToStrip = new StringBuffer("3123");
strippedNumber = "3123";
- phoneUtil.maybeStripNationalPrefix(numberToStrip, nationalPrefix, "", nationalRule);
+ phoneUtil.maybeStripNationalPrefixAndCarrierCode(numberToStrip, metadata);
assertEquals("Should have had no change - after stripping, it wouldn't have matched " +
"the national rule.",
strippedNumber, numberToStrip.toString());
+ // Test extracting carrier selection code.
+ metadata.setNationalPrefixForParsing("0(81)?");
+ numberToStrip = new StringBuffer("08122123456");
+ strippedNumber = "22123456";
+ assertEquals("81", phoneUtil.maybeStripNationalPrefixAndCarrierCode(numberToStrip, metadata));
+ assertEquals("Should have had national prefix and carrier code stripped.",
+ strippedNumber, numberToStrip.toString());
+ // If there was a transform rule, check it was applied.
+ metadata.setNationalPrefixTransformRule("5$15");
+ // Note that a capturing group is present here.
+ metadata.setNationalPrefixForParsing("0(\\d{2})");
+ numberToStrip = new StringBuffer("031123");
+ String transformedNumber = "5315123";
+ phoneUtil.maybeStripNationalPrefixAndCarrierCode(numberToStrip, metadata);
+ assertEquals("Should transform the 031 to a 5315.",
+ transformedNumber, numberToStrip.toString());
}
public void testMaybeStripInternationalPrefix() {
@@ -1236,32 +1145,27 @@ public class PhoneNumberUtilTest extends TestCase {
}
public void testParseNationalNumber() throws Exception {
- PhoneNumber nzNumber = new PhoneNumber();
- nzNumber.setCountryCode(64).setNationalNumber(33316005L);
-
// National prefix attached.
- assertEquals(nzNumber, phoneUtil.parse("033316005", "NZ"));
- assertEquals(nzNumber, phoneUtil.parse("033316005", "nz"));
- assertEquals(nzNumber, phoneUtil.parse("33316005", "NZ"));
+ assertEquals(NZ_NUMBER, phoneUtil.parse("033316005", "NZ"));
+ assertEquals(NZ_NUMBER, phoneUtil.parse("033316005", "nz"));
+ assertEquals(NZ_NUMBER, phoneUtil.parse("33316005", "NZ"));
// National prefix attached and some formatting present.
- assertEquals(nzNumber, phoneUtil.parse("03-331 6005", "NZ"));
- assertEquals(nzNumber, phoneUtil.parse("03 331 6005", "NZ"));
+ assertEquals(NZ_NUMBER, phoneUtil.parse("03-331 6005", "NZ"));
+ assertEquals(NZ_NUMBER, phoneUtil.parse("03 331 6005", "NZ"));
// Testing international prefixes.
// Should strip country code.
- assertEquals(nzNumber, phoneUtil.parse("0064 3 331 6005", "NZ"));
+ assertEquals(NZ_NUMBER, phoneUtil.parse("0064 3 331 6005", "NZ"));
// Try again, but this time we have an international number with Region Code US. It should
// recognise the country code and parse accordingly.
- assertEquals(nzNumber, phoneUtil.parse("01164 3 331 6005", "US"));
- assertEquals(nzNumber, phoneUtil.parse("+64 3 331 6005", "US"));
+ assertEquals(NZ_NUMBER, phoneUtil.parse("01164 3 331 6005", "US"));
+ assertEquals(NZ_NUMBER, phoneUtil.parse("+64 3 331 6005", "US"));
- nzNumber.clear();
+ PhoneNumber nzNumber = new PhoneNumber();
nzNumber.setCountryCode(64).setNationalNumber(64123456L);
assertEquals(nzNumber, phoneUtil.parse("64(0)64123456", "NZ"));
// Check that using a "/" is fine in a phone number.
- PhoneNumber deNumber = new PhoneNumber();
- deNumber.setCountryCode(49).setNationalNumber(12345678L);
- assertEquals(deNumber, phoneUtil.parse("123/45678", "DE"));
+ assertEquals(DE_NUMBER, phoneUtil.parse("301/23456", "DE"));
PhoneNumber usNumber = new PhoneNumber();
// Check it doesn't use the '1' as a country code when parsing if the phone number was already
@@ -1286,48 +1190,43 @@ public class PhoneNumberUtilTest extends TestCase {
}
public void testParseWithInternationalPrefixes() throws Exception {
- PhoneNumber usNumber = new PhoneNumber();
- usNumber.setCountryCode(1).setNationalNumber(6503336000L);
- assertEquals(usNumber, phoneUtil.parse("+1 (650) 333-6000", "NZ"));
- assertEquals(usNumber, phoneUtil.parse("1-650-333-6000", "US"));
+ assertEquals(US_NUMBER, phoneUtil.parse("+1 (650) 253-0000", "NZ"));
+ assertEquals(US_NUMBER, phoneUtil.parse("1-650-253-0000", "US"));
// Calling the US number from Singapore by using different service providers
// 1st test: calling using SingTel IDD service (IDD is 001)
- assertEquals(usNumber, phoneUtil.parse("0011-650-333-6000", "SG"));
+ assertEquals(US_NUMBER, phoneUtil.parse("0011-650-253-0000", "SG"));
// 2nd test: calling using StarHub IDD service (IDD is 008)
- assertEquals(usNumber, phoneUtil.parse("0081-650-333-6000", "SG"));
+ assertEquals(US_NUMBER, phoneUtil.parse("0081-650-253-0000", "SG"));
// 3rd test: calling using SingTel V019 service (IDD is 019)
- assertEquals(usNumber, phoneUtil.parse("0191-650-333-6000", "SG"));
+ assertEquals(US_NUMBER, phoneUtil.parse("0191-650-253-0000", "SG"));
// Calling the US number from Poland
- assertEquals(usNumber, phoneUtil.parse("0~01-650-333-6000", "PL"));
+ assertEquals(US_NUMBER, phoneUtil.parse("0~01-650-253-0000", "PL"));
// Using "++" at the start.
- assertEquals(usNumber, phoneUtil.parse("++1 (650) 333-6000", "PL"));
+ assertEquals(US_NUMBER, phoneUtil.parse("++1 (650) 253-0000", "PL"));
// Using a full-width plus sign.
- assertEquals(usNumber, phoneUtil.parse("\uFF0B1 (650) 333-6000", "SG"));
+ assertEquals(US_NUMBER, phoneUtil.parse("\uFF0B1 (650) 253-0000", "SG"));
// The whole number, including punctuation, is here represented in full-width form.
- assertEquals(usNumber, phoneUtil.parse("\uFF0B\uFF11\u3000\uFF08\uFF16\uFF15\uFF10\uFF09" +
- "\u3000\uFF13\uFF13\uFF13\uFF0D\uFF16\uFF10\uFF10\uFF10",
- "SG"));
+ assertEquals(US_NUMBER, phoneUtil.parse("\uFF0B\uFF11\u3000\uFF08\uFF16\uFF15\uFF10\uFF09" +
+ "\u3000\uFF12\uFF15\uFF13\uFF0D\uFF10\uFF10\uFF10" +
+ "\uFF10",
+ "SG"));
// Using U+30FC dash instead.
- assertEquals(usNumber, phoneUtil.parse("\uFF0B\uFF11\u3000\uFF08\uFF16\uFF15\uFF10\uFF09" +
- "\u3000\uFF13\uFF13\uFF13\u30FC\uFF16\uFF10\uFF10\uFF10",
- "SG"));
+ assertEquals(US_NUMBER, phoneUtil.parse("\uFF0B\uFF11\u3000\uFF08\uFF16\uFF15\uFF10\uFF09" +
+ "\u3000\uFF12\uFF15\uFF13\u30FC\uFF10\uFF10\uFF10" +
+ "\uFF10",
+ "SG"));
}
public void testParseWithLeadingZero() throws Exception {
- PhoneNumber itNumber = new PhoneNumber();
- itNumber.setCountryCode(39).setNationalNumber(236618300L).setItalianLeadingZero(true);
- assertEquals(itNumber, phoneUtil.parse("+39 02-36618 300", "NZ"));
- assertEquals(itNumber, phoneUtil.parse("02-36618 300", "IT"));
+ assertEquals(IT_NUMBER, phoneUtil.parse("+39 02-36618 300", "NZ"));
+ assertEquals(IT_NUMBER, phoneUtil.parse("02-36618 300", "IT"));
- itNumber.clear();
- itNumber.setCountryCode(39).setNationalNumber(312345678L);
- assertEquals(itNumber, phoneUtil.parse("312 345 678", "IT"));
+ assertEquals(IT_MOBILE, phoneUtil.parse("345 678 901", "IT"));
}
public void testParseNationalNumberArgentina() throws Exception {
// Test parsing mobile numbers of Argentina.
PhoneNumber arNumber = new PhoneNumber();
-
arNumber.setCountryCode(54).setNationalNumber(93435551212L);
assertEquals(arNumber, phoneUtil.parse("+54 9 343 555 1212", "AR"));
assertEquals(arNumber, phoneUtil.parse("0343 15 555 1212", "AR"));
@@ -1336,12 +1235,11 @@ public class PhoneNumberUtilTest extends TestCase {
arNumber.setCountryCode(54).setNationalNumber(93715654320L);
assertEquals(arNumber, phoneUtil.parse("+54 9 3715 65 4320", "AR"));
assertEquals(arNumber, phoneUtil.parse("03715 15 65 4320", "AR"));
+ assertEquals(AR_MOBILE, phoneUtil.parse("911 876 54321", "AR"));
// Test parsing fixed-line numbers of Argentina.
- arNumber.clear();
- arNumber.setCountryCode(54).setNationalNumber(1137970000L);
- assertEquals(arNumber, phoneUtil.parse("+54 11 3797 0000", "AR"));
- assertEquals(arNumber, phoneUtil.parse("011 3797 0000", "AR"));
+ assertEquals(AR_NUMBER, phoneUtil.parse("+54 11 8765 4321", "AR"));
+ assertEquals(AR_NUMBER, phoneUtil.parse("011 8765 4321", "AR"));
arNumber.clear();
arNumber.setCountryCode(54).setNationalNumber(3715654321L);
@@ -1356,12 +1254,10 @@ public class PhoneNumberUtilTest extends TestCase {
public void testParseWithXInNumber() throws Exception {
// Test that having an 'x' in the phone number at the start is ok and that it just gets removed.
- PhoneNumber arNumber = new PhoneNumber();
- arNumber.setCountryCode(54).setNationalNumber(123456789L);
- assertEquals(arNumber, phoneUtil.parse("0123456789", "AR"));
- assertEquals(arNumber, phoneUtil.parse("(0) 123456789", "AR"));
- assertEquals(arNumber, phoneUtil.parse("0 123456789", "AR"));
- assertEquals(arNumber, phoneUtil.parse("(0xx) 123456789", "AR"));
+ assertEquals(AR_NUMBER, phoneUtil.parse("01187654321", "AR"));
+ assertEquals(AR_NUMBER, phoneUtil.parse("(0) 1187654321", "AR"));
+ assertEquals(AR_NUMBER, phoneUtil.parse("0 1187654321", "AR"));
+ assertEquals(AR_NUMBER, phoneUtil.parse("(0xx) 1187654321", "AR"));
PhoneNumber arFromUs = new PhoneNumber();
arFromUs.setCountryCode(54).setNationalNumber(81429712L);
// This test is intentionally constructed such that the number of digit after xx is larger than
@@ -1547,21 +1443,25 @@ public class PhoneNumberUtilTest extends TestCase {
}
public void testParseNumbersWithPlusWithNoRegion() throws Exception {
- PhoneNumber nzNumber = new PhoneNumber();
- nzNumber.setCountryCode(64).setNationalNumber(33316005L);
// "ZZ" is allowed only if the number starts with a '+' - then the country code can be
// calculated.
- assertEquals(nzNumber, phoneUtil.parse("+64 3 331 6005", "ZZ"));
+ assertEquals(NZ_NUMBER, phoneUtil.parse("+64 3 331 6005", "ZZ"));
// Test with full-width plus.
- assertEquals(nzNumber, phoneUtil.parse("\uFF0B64 3 331 6005", "ZZ"));
+ assertEquals(NZ_NUMBER, phoneUtil.parse("\uFF0B64 3 331 6005", "ZZ"));
// Test with normal plus but leading characters that need to be stripped.
- assertEquals(nzNumber, phoneUtil.parse("Tel: +64 3 331 6005", "ZZ"));
- assertEquals(nzNumber, phoneUtil.parse("+64 3 331 6005", null));
- nzNumber.setRawInput("+64 3 331 6005").
- setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN);
- assertEquals(nzNumber, phoneUtil.parseAndKeepRawInput("+64 3 331 6005", "ZZ"));
+ assertEquals(NZ_NUMBER, phoneUtil.parse("Tel: +64 3 331 6005", "ZZ"));
+ assertEquals(NZ_NUMBER, phoneUtil.parse("+64 3 331 6005", null));
+
+ // It is important that we set the carrier code to an empty string, since we used
+ // ParseAndKeepRawInput and no carrier code was found.
+ PhoneNumber nzNumberWithRawInput = new PhoneNumber().mergeFrom(NZ_NUMBER).
+ setRawInput("+64 3 331 6005").
+ setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN).
+ setPreferredDomesticCarrierCode("");
+ assertEquals(nzNumberWithRawInput, phoneUtil.parseAndKeepRawInput("+64 3 331 6005",
+ "ZZ"));
// Null is also allowed for the region code in these cases.
- assertEquals(nzNumber, phoneUtil.parseAndKeepRawInput("+64 3 331 6005", null));
+ assertEquals(nzNumberWithRawInput, phoneUtil.parseAndKeepRawInput("+64 3 331 6005", null));
}
public void testParseExtensions() throws Exception {
@@ -1572,15 +1472,12 @@ public class PhoneNumberUtilTest extends TestCase {
assertEquals(nzNumber, phoneUtil.parse("03-3316005 int.3456", "NZ"));
assertEquals(nzNumber, phoneUtil.parse("03 3316005 #3456", "NZ"));
// Test the following do not extract extensions:
- PhoneNumber nonExtnNumber = new PhoneNumber();
- nonExtnNumber.setCountryCode(1).setNationalNumber(80074935247L);
- assertEquals(nonExtnNumber, phoneUtil.parse("1800 six-flags", "US"));
- assertEquals(nonExtnNumber, phoneUtil.parse("1800 SIX FLAGS", "US"));
- assertEquals(nonExtnNumber, phoneUtil.parse("0~0 1800 7493 5247", "PL"));
- assertEquals(nonExtnNumber, phoneUtil.parse("(1800) 7493.5247", "US"));
+ assertEquals(ALPHA_NUMERIC_NUMBER, phoneUtil.parse("1800 six-flags", "US"));
+ assertEquals(ALPHA_NUMERIC_NUMBER, phoneUtil.parse("1800 SIX FLAGS", "US"));
+ assertEquals(ALPHA_NUMERIC_NUMBER, phoneUtil.parse("0~0 1800 7493 5247", "PL"));
+ assertEquals(ALPHA_NUMERIC_NUMBER, phoneUtil.parse("(1800) 7493.5247", "US"));
// Check that the last instance of an extension token is matched.
- PhoneNumber extnNumber = new PhoneNumber();
- extnNumber.setCountryCode(1).setNationalNumber(80074935247L).setExtension("1234");
+ PhoneNumber extnNumber = new PhoneNumber().mergeFrom(ALPHA_NUMERIC_NUMBER).setExtension("1234");
assertEquals(extnNumber, phoneUtil.parse("0~0 1800 7493 5247 ~1234", "PL"));
// Verifying bug-fix where the last digit of a number was previously omitted if it was a 0 when
// extracting the extension. Also verifying a few different cases of extensions.
@@ -1629,29 +1526,29 @@ public class PhoneNumberUtilTest extends TestCase {
}
public void testParseAndKeepRaw() throws Exception {
- PhoneNumber alphaNumericNumber = new PhoneNumber();
- alphaNumericNumber.
- setCountryCode(1).setNationalNumber(80074935247L).setRawInput("800 six-flags").
- setCountryCodeSource(CountryCodeSource.FROM_DEFAULT_COUNTRY);
+ PhoneNumber alphaNumericNumber = new PhoneNumber().mergeFrom(ALPHA_NUMERIC_NUMBER).
+ setRawInput("800 six-flags").
+ setCountryCodeSource(CountryCodeSource.FROM_DEFAULT_COUNTRY).
+ setPreferredDomesticCarrierCode("");
assertEquals(alphaNumericNumber,
phoneUtil.parseAndKeepRawInput("800 six-flags", "US"));
- alphaNumericNumber.
- setCountryCode(1).setNationalNumber(8007493524L).setRawInput("1800 six-flag").
- setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN);
- assertEquals(alphaNumericNumber,
+ PhoneNumber shorterAlphaNumber = new PhoneNumber().
+ setCountryCode(1).setNationalNumber(8007493524L).
+ setRawInput("1800 six-flag").
+ setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN).
+ setPreferredDomesticCarrierCode("");
+ assertEquals(shorterAlphaNumber,
phoneUtil.parseAndKeepRawInput("1800 six-flag", "US"));
- alphaNumericNumber.
- setCountryCode(1).setNationalNumber(8007493524L).setRawInput("+1800 six-flag").
+ shorterAlphaNumber.setRawInput("+1800 six-flag").
setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN);
- assertEquals(alphaNumericNumber,
+ assertEquals(shorterAlphaNumber,
phoneUtil.parseAndKeepRawInput("+1800 six-flag", "NZ"));
- alphaNumericNumber.
- setCountryCode(1).setNationalNumber(8007493524L).setRawInput("001800 six-flag").
+ shorterAlphaNumber.setRawInput("001800 six-flag").
setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_IDD);
- assertEquals(alphaNumericNumber,
+ assertEquals(shorterAlphaNumber,
phoneUtil.parseAndKeepRawInput("001800 six-flag", "NZ"));
// Invalid region code supplied.
@@ -1664,6 +1561,12 @@ public class PhoneNumberUtilTest extends TestCase {
NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
e.getErrorType());
}
+
+ PhoneNumber koreanNumber = new PhoneNumber();
+ koreanNumber.setCountryCode(82).setNationalNumber(22123456).setRawInput("08122123456").
+ setCountryCodeSource(CountryCodeSource.FROM_DEFAULT_COUNTRY).
+ setPreferredDomesticCarrierCode("81");
+ assertEquals(koreanNumber, phoneUtil.parseAndKeepRawInput("08122123456", "KR"));
}
public void testCountryWithNoNumberDesc() {
@@ -1677,10 +1580,8 @@ public class PhoneNumberUtilTest extends TestCase {
assertTrue(phoneUtil.isValidNumber(adNumber));
// Test dialing a US number from within Andorra.
- PhoneNumber usNumber = new PhoneNumber();
- usNumber.setCountryCode(1).setNationalNumber(6502530000L);
assertEquals("00 1 650 253 0000",
- phoneUtil.formatOutOfCountryCallingNumber(usNumber, "AD"));
+ phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER, "AD"));
}
public void testUnknownCountryCallingCodeForValidation() {
@@ -1709,23 +1610,32 @@ public class PhoneNumberUtilTest extends TestCase {
assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
phoneUtil.isNumberMatch("+64 3 331-6005 extn 1234", "+6433316005#1234"));
// Test proto buffers.
- PhoneNumber nzNumber = new PhoneNumber();
- nzNumber.setCountryCode(64).setNationalNumber(33316005L).setExtension("3456");
assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
- phoneUtil.isNumberMatch(nzNumber, "+643 331 6005 ext 3456"));
- nzNumber.clearExtension();
+ phoneUtil.isNumberMatch(NZ_NUMBER, "+6403 331 6005"));
+
+ PhoneNumber nzNumber = new PhoneNumber().mergeFrom(NZ_NUMBER).setExtension("3456");
assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
- phoneUtil.isNumberMatch(nzNumber, "+6403 331 6005"));
+ phoneUtil.isNumberMatch(nzNumber, "+643 331 6005 ext 3456"));
// Check empty extensions are ignored.
nzNumber.setExtension("");
assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
phoneUtil.isNumberMatch(nzNumber, "+6403 331 6005"));
// Check variant with two proto buffers.
- PhoneNumber nzNumberTwo = new PhoneNumber();
- nzNumberTwo.setCountryCode(64).setNationalNumber(33316005L);
- assertEquals("Number " + nzNumber.toString() + " did not match " + nzNumberTwo.toString(),
+ assertEquals("Number " + nzNumber.toString() + " did not match " + NZ_NUMBER.toString(),
PhoneNumberUtil.MatchType.EXACT_MATCH,
- phoneUtil.isNumberMatch(nzNumber, nzNumberTwo));
+ phoneUtil.isNumberMatch(nzNumber, NZ_NUMBER));
+
+ // Check raw_input, country_code_source and preferred_domestic_carrier_code are ignored.
+ PhoneNumber brNumberOne = new PhoneNumber();
+ PhoneNumber brNumberTwo = new PhoneNumber();
+ brNumberOne.setCountryCode(55).setNationalNumber(3121286979L)
+ .setCountryCodeSource(PhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN)
+ .setPreferredDomesticCarrierCode("12").setRawInput("012 3121286979");
+ brNumberTwo.setCountryCode(55).setNationalNumber(3121286979L)
+ .setCountryCodeSource(PhoneNumber.CountryCodeSource.FROM_DEFAULT_COUNTRY)
+ .setPreferredDomesticCarrierCode("14").setRawInput("143121286979");
+ assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
+ phoneUtil.isNumberMatch(brNumberOne, brNumberTwo));
}
public void testIsNumberMatchNonMatches() throws Exception {
@@ -1748,7 +1658,6 @@ public class PhoneNumberUtilTest extends TestCase {
// Invalid numbers that can't be parsed.
assertEquals(PhoneNumberUtil.MatchType.NOT_A_NUMBER,
phoneUtil.isNumberMatch("43", "3 331 6043"));
- // Invalid numbers that can't be parsed.
assertEquals(PhoneNumberUtil.MatchType.NOT_A_NUMBER,
phoneUtil.isNumberMatch("+43", "+64 3 331 6005"));
assertEquals(PhoneNumberUtil.MatchType.NOT_A_NUMBER,
@@ -1763,39 +1672,34 @@ public class PhoneNumberUtilTest extends TestCase {
phoneUtil.isNumberMatch("+64 3 331-6005", "03 331 6005"));
assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
phoneUtil.isNumberMatch("3 331-6005", "03 331 6005"));
- PhoneNumber nzNumber = new PhoneNumber();
- nzNumber.setCountryCode(64).setNationalNumber(33316005L).setExtension("");
assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
- phoneUtil.isNumberMatch(nzNumber, "03 331 6005"));
+ phoneUtil.isNumberMatch(NZ_NUMBER, "03 331 6005"));
// Here the second number possibly starts with the country code for New Zealand, although we are
// unsure.
+ PhoneNumber unchangedNzNumber = new PhoneNumber().mergeFrom(NZ_NUMBER);
assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
- phoneUtil.isNumberMatch(nzNumber, "(64-3) 331 6005"));
- PhoneNumber unchangedNzNumber = new PhoneNumber();
- unchangedNzNumber.setCountryCode(64).setNationalNumber(33316005L).setExtension("");
+ phoneUtil.isNumberMatch(unchangedNzNumber, "(64-3) 331 6005"));
// Check the phone number proto was not edited during the method call.
- assertEquals(unchangedNzNumber, nzNumber);
+ assertEquals(NZ_NUMBER, unchangedNzNumber);
// Here, the 1 might be a national prefix, if we compare it to the US number, so the resultant
// match is an NSN match.
- PhoneNumber usNumber = new PhoneNumber();
- usNumber.setCountryCode(1).setNationalNumber(2345678901L).setExtension("");
assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
- phoneUtil.isNumberMatch(usNumber, "1-234-567-8901"));
+ phoneUtil.isNumberMatch(US_NUMBER, "1-650-253-0000"));
assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
- phoneUtil.isNumberMatch(usNumber, "2345678901"));
+ phoneUtil.isNumberMatch(US_NUMBER, "6502530000"));
assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
- phoneUtil.isNumberMatch("+1 234-567 8901", "1 234 567 8901"));
+ phoneUtil.isNumberMatch("+1 650-253 0000", "1 650 253 0000"));
assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
- phoneUtil.isNumberMatch("1 234-567 8901", "1 234 567 8901"));
+ phoneUtil.isNumberMatch("1 650-253 0000", "1 650 253 0000"));
assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
- phoneUtil.isNumberMatch("1 234-567 8901", "+1 234 567 8901"));
+ phoneUtil.isNumberMatch("1 650-253 0000", "+1 650 253 0000"));
// For this case, the match will be a short NSN match, because we cannot assume that the 1 might
// be a national prefix, so don't remove it when parsing.
PhoneNumber randomNumber = new PhoneNumber();
- randomNumber.setCountryCode(41).setNationalNumber(2345678901L).setExtension("");
+ randomNumber.setCountryCode(41).setNationalNumber(6502530000L);
assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
- phoneUtil.isNumberMatch(randomNumber, "1-234-567-8901"));
+ phoneUtil.isNumberMatch(randomNumber, "1-650-253-0000"));
}
public void testIsNumberMatchShortNsnMatches() throws Exception {
@@ -1831,23 +1735,17 @@ public class PhoneNumberUtilTest extends TestCase {
}
public void testCanBeInternationallyDialled() throws Exception {
- // We have no-international-dialling rules for the US in our test metadata.
- PhoneNumber usNumber = new PhoneNumber();
- usNumber.setCountryCode(1).setNationalNumber(8001231234L);
- assertFalse(phoneUtil.canBeInternationallyDialled(usNumber));
+ // We have no-international-dialling rules for the US in our test metadata that say that
+ // toll-free numbers cannot be dialled internationally.
+ assertFalse(phoneUtil.canBeInternationallyDialled(US_TOLLFREE));
- PhoneNumber usInternationalNumber = new PhoneNumber();
- usInternationalNumber.setCountryCode(1).setNationalNumber(2311231234L);
- assertTrue(phoneUtil.canBeInternationallyDialled(usInternationalNumber));
+ // Normal US numbers can be internationally dialled.
+ assertTrue(phoneUtil.canBeInternationallyDialled(US_NUMBER));
- PhoneNumber usInvalidNumber = new PhoneNumber();
// Invalid number.
- usInvalidNumber.setCountryCode(1).setNationalNumber(13112312L);
- assertTrue(phoneUtil.canBeInternationallyDialled(usInvalidNumber));
+ assertTrue(phoneUtil.canBeInternationallyDialled(US_LOCAL_NUMBER));
// We have no data for NZ - should return true.
- PhoneNumber nzNumber = new PhoneNumber();
- nzNumber.setCountryCode(64).setNationalNumber(33316005L);
- assertTrue(phoneUtil.canBeInternationallyDialled(nzNumber));
+ assertTrue(phoneUtil.canBeInternationallyDialled(NZ_NUMBER));
}
}
diff --git a/java/test/com/google/i18n/phonenumbers/PhonenumberTest.java b/java/test/com/google/i18n/phonenumbers/PhonenumberTest.java
index b77b9d1f3..5f35bb090 100644
--- a/java/test/com/google/i18n/phonenumbers/PhonenumberTest.java
+++ b/java/test/com/google/i18n/phonenumbers/PhonenumberTest.java
@@ -28,7 +28,7 @@ import junit.framework.TestCase;
*/
public class PhonenumberTest extends TestCase {
- public void testEqualsSimpleNumber() throws Exception {
+ public void testEqualSimpleNumber() throws Exception {
PhoneNumber numberA = new PhoneNumber();
numberA.setCountryCode(1).setNationalNumber(6502530000L);
@@ -39,7 +39,7 @@ public class PhonenumberTest extends TestCase {
assertEquals(numberA.hashCode(), numberB.hashCode());
}
- public void testEqualsWithOtherFields() throws Exception {
+ public void testEqualWithItalianLeadingZeroSetToDefault() throws Exception {
PhoneNumber numberA = new PhoneNumber();
numberA.setCountryCode(1).setNationalNumber(6502530000L).setItalianLeadingZero(false);
@@ -49,16 +49,20 @@ public class PhonenumberTest extends TestCase {
// These should still be equal, since the default value for this field is false.
assertEquals(numberA, numberB);
assertEquals(numberA.hashCode(), numberB.hashCode());
+ }
+ public void testEqualWithCountryCodeSourceSet() throws Exception {
+ PhoneNumber numberA = new PhoneNumber();
numberA.setRawInput("+1 650 253 00 00").
setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN);
+ PhoneNumber numberB = new PhoneNumber();
numberB.setRawInput("+1 650 253 00 00").
setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN);
assertEquals(numberA, numberB);
assertEquals(numberA.hashCode(), numberB.hashCode());
}
- public void testNonEqualWithOtherFields() throws Exception {
+ public void testNonEqualWithItalianLeadingZeroSetToTrue() throws Exception {
PhoneNumber numberA = new PhoneNumber();
numberA.setCountryCode(1).setNationalNumber(6502530000L).setItalianLeadingZero(true);
@@ -69,7 +73,7 @@ public class PhonenumberTest extends TestCase {
assertFalse(numberA.hashCode() == numberB.hashCode());
}
- public void testNonEqualWithAllFields() throws Exception {
+ public void testNonEqualWithDifferingRawInput() throws Exception {
PhoneNumber numberA = new PhoneNumber();
numberA.setCountryCode(1).setNationalNumber(6502530000L).setRawInput("+1 650 253 00 00").
setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN);
@@ -83,4 +87,26 @@ public class PhonenumberTest extends TestCase {
assertFalse(numberA.equals(numberB));
assertFalse(numberA.hashCode() == numberB.hashCode());
}
+
+ public void testNonEqualWithPreferredDomesticCarrierCodeSetToDefault() throws Exception {
+ PhoneNumber numberA = new PhoneNumber();
+ numberA.setCountryCode(1).setNationalNumber(6502530000L).setPreferredDomesticCarrierCode("");
+
+ PhoneNumber numberB = new PhoneNumber();
+ numberB.setCountryCode(1).setNationalNumber(6502530000L);
+
+ assertFalse(numberA.equals(numberB));
+ assertFalse(numberA.hashCode() == numberB.hashCode());
+ }
+
+ public void testEqualWithPreferredDomesticCarrierCodeSetToDefault() throws Exception {
+ PhoneNumber numberA = new PhoneNumber();
+ numberA.setCountryCode(1).setNationalNumber(6502530000L).setPreferredDomesticCarrierCode("");
+
+ PhoneNumber numberB = new PhoneNumber();
+ numberB.setCountryCode(1).setNationalNumber(6502530000L).setPreferredDomesticCarrierCode("");
+
+ assertEquals(numberA, numberB);
+ assertEquals(numberA.hashCode(), numberB.hashCode());
+ }
}
diff --git a/java/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AR b/java/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AR
index 4a9b091ee..e2efc8f10 100644
Binary files a/java/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AR and b/java/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AR differ
diff --git a/java/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_DE b/java/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_DE
index b2f1c5aa4..82b22fb77 100644
Binary files a/java/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_DE and b/java/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_DE differ
diff --git a/java/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_KR b/java/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_KR
index aad7e4146..7c2b9421e 100644
Binary files a/java/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_KR and b/java/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_KR differ