diff --git a/csharp/PhoneNumbers.Test/TestPhoneNumberUtil.cs b/csharp/PhoneNumbers.Test/TestPhoneNumberUtil.cs index 088647011..572957aca 100644 --- a/csharp/PhoneNumbers.Test/TestPhoneNumberUtil.cs +++ b/csharp/PhoneNumbers.Test/TestPhoneNumberUtil.cs @@ -324,6 +324,21 @@ public void TestGetNationalSignificantNumber() Assert.Equal("12345678", phoneUtil.GetNationalSignificantNumber(InternationalTollFree)); } + [Fact] + public void TestGetNationalSignificantNumber_ManyLeadingZeros() + { + var number = new PhoneNumber.Builder() + .SetCountryCode(1) + .SetNationalNumber(650) + .SetItalianLeadingZero(true) + .SetNumberOfLeadingZeros(2) + .Build(); + Assert.Equal("00650", phoneUtil.GetNationalSignificantNumber(number)); + // Set a bad value; we shouldn't crash, we shouldn't output any leading zeros at all. + number = Update(number).SetNumberOfLeadingZeros(-3).Build(); + Assert.Equal("650", phoneUtil.GetNationalSignificantNumber(number)); + } + [Fact] public void TestGetExampleNumber() { @@ -793,6 +808,16 @@ public void TestFormatNumberForMobileDialing() phoneUtil.FormatNumberForMobileDialing(InternationalTollFree, RegionCode.JP, false)); Assert.Equal("+800 1234 5678", phoneUtil.FormatNumberForMobileDialing(InternationalTollFree, RegionCode.JP, true)); + + // Test that the Australian emergency number 000 is formatted correctly. + var auNumber = new PhoneNumber.Builder() + .SetCountryCode(61) + .SetNationalNumber(0L) + .SetItalianLeadingZero(true) + .SetNumberOfLeadingZeros(2) + .Build(); + Assert.Equal("000", phoneUtil.FormatNumberForMobileDialing(auNumber, RegionCode.AU, false)); + Assert.Equal("", phoneUtil.FormatNumberForMobileDialing(auNumber, RegionCode.NZ, false)); } [Fact] @@ -2366,6 +2391,45 @@ public void TestParseAndKeepRaw() Assert.Equal(koreanNumber, phoneUtil.ParseAndKeepRawInput("08122123456", RegionCode.KR)); } + [Fact] + public void TestParseItalianLeadingZeros() + { + // Test the number "011". + var oneZero = new PhoneNumber.Builder() + .SetCountryCode(61) + .SetNationalNumber(11L) + .SetItalianLeadingZero(true) + .Build(); + Assert.Equal(oneZero, phoneUtil.Parse("011", RegionCode.AU)); + + // Test the number "001". + var twoZeros = new PhoneNumber.Builder() + .SetCountryCode(61) + .SetNationalNumber(1) + .SetItalianLeadingZero(true) + .SetNumberOfLeadingZeros(2) + .Build(); + Assert.Equal(twoZeros, phoneUtil.Parse("001", RegionCode.AU)); + + // Test the number "000". This number has 2 leading zeros. + var stillTwoZeros = new PhoneNumber.Builder() + .SetCountryCode(61) + .SetNationalNumber(0L) + .SetItalianLeadingZero(true) + .SetNumberOfLeadingZeros(2) + .Build(); + Assert.Equal(stillTwoZeros, phoneUtil.Parse("000", RegionCode.AU)); + + // Test the number "0000". This number has 3 leading zeros. + var threeZeros = new PhoneNumber.Builder() + .SetCountryCode(61) + .SetNationalNumber(0L) + .SetItalianLeadingZero(true) + .SetNumberOfLeadingZeros(3) + .Build(); + Assert.Equal(threeZeros, phoneUtil.Parse("0000", RegionCode.AU)); + } + [Fact] public void TestCountryWithNoNumberDesc() { @@ -2445,6 +2509,51 @@ public void TestIsNumberMatchMatches() phoneUtil.IsNumberMatch(brNumberOne, brNumberTwo)); } + [Fact] + public void TestIsNumberMatchShortMatchIfDiffNumLeadingZeros() + { + var nzNumberOne = new PhoneNumber.Builder() + .SetCountryCode(64).SetNationalNumber(33316005L).SetItalianLeadingZero(true).Build(); + var nzNumberTwo = new PhoneNumber.Builder() + .SetCountryCode(64).SetNationalNumber(33316005L).SetItalianLeadingZero(true).SetNumberOfLeadingZeros(2).Build(); + Assert.Equal(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH, phoneUtil.IsNumberMatch(nzNumberOne, nzNumberTwo)); + + nzNumberOne = Update(nzNumberOne).SetItalianLeadingZero(false).SetNumberOfLeadingZeros(1).Build(); + nzNumberTwo = Update(nzNumberTwo).SetItalianLeadingZero(true).SetNumberOfLeadingZeros(1).Build(); + // Since one doesn't have the "italian_leading_zero" set to true, we ignore the number of + // leading zeros present (1 is in any case the default value). + Assert.Equal(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH, phoneUtil.IsNumberMatch(nzNumberOne, nzNumberTwo)); + } + + [Fact] + public void TestIsNumberMatchAcceptsProtoDefaultsAsMatch() + { + var nzNumberOne = new PhoneNumber.Builder() + .SetCountryCode(64).SetNationalNumber(33316005L).SetItalianLeadingZero(true).Build(); + // The default for number_of_leading_zeros is 1, so it shouldn't normally be set, however if it + // is it should be considered equivalent. + var nzNumberTwo = new PhoneNumber.Builder() + .SetCountryCode(64).SetNationalNumber(33316005L).SetItalianLeadingZero(true).SetNumberOfLeadingZeros(1).Build(); + Assert.Equal(PhoneNumberUtil.MatchType.EXACT_MATCH, phoneUtil.IsNumberMatch(nzNumberOne, nzNumberTwo)); + } + + [Fact] + public void TestIsNumberMatchMatchesDiffLeadingZerosIfItalianLeadingZeroFalse() + { + var nzNumberOne = new PhoneNumber.Builder() + .SetCountryCode(64).SetNationalNumber(33316005L).Build(); + // The default for number_of_leading_zeros is 1, so it shouldn't normally be set, however if it + // is it should be considered equivalent. + var nzNumberTwo = new PhoneNumber.Builder() + .SetCountryCode(64).SetNationalNumber(33316005L).SetNumberOfLeadingZeros(1).Build(); + Assert.Equal(PhoneNumberUtil.MatchType.EXACT_MATCH, phoneUtil.IsNumberMatch(nzNumberOne, nzNumberTwo)); + + // Even if it is set to ten, it is still equivalent because in both cases + // italian_leading_zero is not true. + nzNumberTwo = Update(nzNumberTwo).SetNumberOfLeadingZeros(10).Build(); + Assert.Equal(PhoneNumberUtil.MatchType.EXACT_MATCH, phoneUtil.IsNumberMatch(nzNumberOne, nzNumberTwo)); + } + [Fact] public void TestIsNumberMatchNonMatches() { diff --git a/csharp/PhoneNumbers/PhoneNumberUtil.cs b/csharp/PhoneNumbers/PhoneNumberUtil.cs index b206bb2d9..ea52ffc8d 100644 --- a/csharp/PhoneNumbers/PhoneNumberUtil.cs +++ b/csharp/PhoneNumbers/PhoneNumberUtil.cs @@ -1796,8 +1796,10 @@ public string FormatOutOfCountryKeepingAlphaChars(PhoneNumber number, string reg /// The national significant number of the PhoneNumber object passed in. public string GetNationalSignificantNumber(PhoneNumber number) { - // If a leading zero has been set, we prefix this now. Note this is not a national prefix. - var nationalNumber = new StringBuilder(number.ItalianLeadingZero ? "0" : ""); + // If a leading zero(s) has been set, we prefix this now. Note this is not a national prefix. + var nationalNumber = new StringBuilder(); + if (number.ItalianLeadingZero && number.NumberOfLeadingZeros > 0) + nationalNumber.Append('0', number.NumberOfLeadingZeros); nationalNumber.Append(number.NationalNumber); return nationalNumber.ToString(); } @@ -3268,6 +3270,12 @@ public MatchType IsNumberMatch(PhoneNumber firstNumberIn, PhoneNumber secondNumb secondNumber.Extension.Length == 0) secondNumber.ClearExtension(); + // This field is only relevant if there are leading zeros at all. + if (!firstNumber.ItalianLeadingZero) + firstNumber.ClearNumberOfLeadingZeros(); + if (!secondNumber.ItalianLeadingZero) + secondNumber.ClearNumberOfLeadingZeros(); + // Early exit if both had extensions and these are different. if (firstNumber.HasExtension && secondNumber.HasExtension && !firstNumber.Extension.Equals(secondNumber.Extension)) diff --git a/csharp/PhoneNumbers/Phonenumber.cs b/csharp/PhoneNumbers/Phonenumber.cs index 4d610ecb0..5faf87ea7 100644 --- a/csharp/PhoneNumbers/Phonenumber.cs +++ b/csharp/PhoneNumbers/Phonenumber.cs @@ -379,8 +379,7 @@ public override bool Equals(object obj) if (HasExtension != other.HasExtension || HasExtension && !Extension.Equals(other.Extension)) return false; if (HasItalianLeadingZero != other.HasItalianLeadingZero || HasItalianLeadingZero && !ItalianLeadingZero.Equals(other.ItalianLeadingZero)) return false; - if (HasNumberOfLeadingZeros != other.HasNumberOfLeadingZeros || HasNumberOfLeadingZeros && - !NumberOfLeadingZeros.Equals(other.NumberOfLeadingZeros)) return false; + if (!NumberOfLeadingZeros.Equals(other.NumberOfLeadingZeros)) return false; if (HasRawInput != other.HasRawInput || HasRawInput && !RawInput.Equals(other.RawInput)) return false; if (HasCountryCodeSource != other.HasCountryCodeSource || HasCountryCodeSource && !CountryCodeSource.Equals(other.CountryCodeSource)) return false;