Skip to content

Commit

Permalink
Closes #619
Browse files Browse the repository at this point in the history
Add support for Liechtenstein phone numbers
  • Loading branch information
TrevorPilley committed Nov 25, 2024
1 parent ea181fe commit 06a8abe
Show file tree
Hide file tree
Showing 10 changed files with 242 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ Jersey | JE | 44 _(UK)_ | 0 | Yes | Yes
Kosovo | XK | 383 | 0 | Yes | Yes | | | Yes | Yes | Yes | Yes |
Latvia | LV | 371 | | Yes | Yes | | | Yes | Yes | Yes | Yes |
Lithuania | LT | 370 | 8 | Yes | Yes | | Yes | Yes | Yes | Yes | Yes |
Liechtenstein | LI | 423 | | | Yes | | Yes | Yes | Yes | Yes | Yes |
Luxembourg | LU | 352 | | | Yes | | | Yes | Yes | Yes | | Yes
Malta | MT | 356 | | Yes | Yes | Yes | | Yes | Yes | Yes | | Yes
Moldova | MD | 373 | 0 | Yes | Yes | | | Yes | Yes | Yes | Yes |
Expand Down
13 changes: 13 additions & 0 deletions src/PhoneNumbers/CountryInfo_Europe.cs
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,19 @@ public partial class CountryInfo
NsnLengths = new ReadOnlyCollection<int>([8]),
};

/// <summary>
/// Gets the <see cref="CountryInfo"/> for Liechtenstein.
/// </summary>
public static CountryInfo Liechtenstein { get; } = new()
{
CallingCode = "423",
Continent = Europe,
FormatProvider = LIPhoneNumberFormatProvider.Instance,
Iso3166Code = "LI",
Name = "Liechtenstein",
NsnLengths = new ReadOnlyCollection<int>([7, 9]),
};

/// <summary>
/// Gets the <see cref="CountryInfo"/> for Lithuania.
/// </summary>
Expand Down
11 changes: 11 additions & 0 deletions src/PhoneNumbers/DataFiles/LI.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Reference: https://archiv.llv.li/files/ak/pdf-llv-ak-liechtenstein_numbering_plan.pdf via https://www.llv.li/en/national-administration/office-for-communications/electronic-communication/numbering/liechtenstein-numbering-plan-itu-t-e.164-
# Reference Date: 01/03/2017
N|||2000000-3999999|
M|||600000000-689999999|
M|||690000000-699999999|
M|||7000000-7999999|
N|||8000000-8099999|F
N|||8400000-8499999|S
N|||8700000-8799999|
M|||8900000-8999999|V
N|||9000000-9019999,9060000-9069999|R
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace PhoneNumbers.Formatters.FormatProviders;

/// <summary>
/// A <see cref="PhoneNumberFormatProvider"/> for Liechtenstein numbers.
/// </summary>
internal sealed class LIPhoneNumberFormatProvider : SimplePhoneNumberFormatProvider
{
private LIPhoneNumberFormatProvider()
{
}

internal static PhoneNumberFormatProvider Instance { get; } = new LIPhoneNumberFormatProvider();

protected override string ProvideFormat(PhoneNumber phoneNumber, bool international) =>
phoneNumber.NationalSignificantNumber.Length switch
{
7 => "### ## ##",
9 => "### ### ###",
_ => base.ProvideFormat(phoneNumber, international),
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
namespace PhoneNumbers.Tests.Parsers;

/// <summary>
/// Contains unit tests for the <see cref="DefaultPhoneNumberParser"/> class for Liechtenstein <see cref="PhoneNumber"/>s.
/// </summary>
public class DefaultPhoneNumberParserTests_LI_MobilePhoneNumber
{
private static readonly PhoneNumberParser s_parser = DefaultPhoneNumberParser.Create(CountryInfo.Liechtenstein);

[Theory]
[InlineData("7000000", "7000000")]
[InlineData("7999999", "7999999")]
[InlineData("600000000", "600000000")]
[InlineData("689999999", "689999999")]
[InlineData("690000000", "690000000")]
[InlineData("699999999", "699999999")]
public void Parse_Known_MobilePhoneNumber(string value, string subscriberNumber)
{
var parseResult = s_parser.Parse(value);
parseResult.ThrowIfFailure();

var phoneNumber = parseResult.PhoneNumber;

Assert.NotNull(phoneNumber);
Assert.IsType<MobilePhoneNumber>(phoneNumber);

var mobilePhoneNumber = (MobilePhoneNumber)phoneNumber;
Assert.Equal(CountryInfo.Liechtenstein, mobilePhoneNumber.Country);
Assert.False(mobilePhoneNumber.IsPager);
Assert.False(mobilePhoneNumber.IsVirtual);
Assert.Null(mobilePhoneNumber.NationalDestinationCode);
Assert.Equal(subscriberNumber, mobilePhoneNumber.SubscriberNumber);
}

[Theory]
[InlineData("8900000", "8900000")]
[InlineData("8999999", "8999999")]
public void Parse_Known_MobilePhoneNumber_Virtual(string value, string subscriberNumber)
{
var parseResult = s_parser.Parse(value);
parseResult.ThrowIfFailure();

var phoneNumber = parseResult.PhoneNumber;

Assert.NotNull(phoneNumber);
Assert.IsType<MobilePhoneNumber>(phoneNumber);

var mobilePhoneNumber = (MobilePhoneNumber)phoneNumber;
Assert.Equal(CountryInfo.Liechtenstein, mobilePhoneNumber.Country);
Assert.False(mobilePhoneNumber.IsPager);
Assert.True(mobilePhoneNumber.IsVirtual);
Assert.Null(mobilePhoneNumber.NationalDestinationCode);
Assert.Equal(subscriberNumber, mobilePhoneNumber.SubscriberNumber);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
namespace PhoneNumbers.Tests.Parsers;

/// <summary>
/// Contains unit tests for the <see cref="DefaultPhoneNumberParser"/> class for Liechtenstein <see cref="PhoneNumber"/>s.
/// </summary>
public class DefaultPhoneNumberParserTests_LI_NonGeographicPhoneNumber
{
private static readonly PhoneNumberParser s_parser = DefaultPhoneNumberParser.Create(CountryInfo.Liechtenstein);

[Theory]
[InlineData("2000000", "2000000")]
[InlineData("3999999", "3999999")]
[InlineData("8700000", "8700000")]
[InlineData("8799999", "8799999")]
public void Parse_Known_NonGeographicPhoneNumber(string value, string subscriberNumber)
{
var parseResult = s_parser.Parse(value);
parseResult.ThrowIfFailure();

var phoneNumber = parseResult.PhoneNumber;

Assert.NotNull(phoneNumber);
Assert.IsType<NonGeographicPhoneNumber>(phoneNumber);

var nonGeographicPhoneNumber = (NonGeographicPhoneNumber)phoneNumber;
Assert.Equal(CountryInfo.Liechtenstein, nonGeographicPhoneNumber.Country);
Assert.False(nonGeographicPhoneNumber.IsFreephone);
Assert.False(nonGeographicPhoneNumber.IsMachineToMachine);
Assert.False(nonGeographicPhoneNumber.IsPremiumRate);
Assert.False(nonGeographicPhoneNumber.IsSharedCost);
Assert.Null(nonGeographicPhoneNumber.NationalDestinationCode);
Assert.Equal(subscriberNumber, nonGeographicPhoneNumber.SubscriberNumber);
}

[Theory]
[InlineData("8000000", "8000000")]
[InlineData("8099999", "8099999")]
public void Parse_Known_NonGeographicPhoneNumber_Freephone(string value, string subscriberNumber)
{
var parseResult = s_parser.Parse(value);
parseResult.ThrowIfFailure();

var phoneNumber = parseResult.PhoneNumber;

Assert.NotNull(phoneNumber);
Assert.IsType<NonGeographicPhoneNumber>(phoneNumber);

var nonGeographicPhoneNumber = (NonGeographicPhoneNumber)phoneNumber;
Assert.Equal(CountryInfo.Liechtenstein, nonGeographicPhoneNumber.Country);
Assert.True(nonGeographicPhoneNumber.IsFreephone);
Assert.False(nonGeographicPhoneNumber.IsMachineToMachine);
Assert.False(nonGeographicPhoneNumber.IsPremiumRate);
Assert.False(nonGeographicPhoneNumber.IsSharedCost);
Assert.Null(nonGeographicPhoneNumber.NationalDestinationCode);
Assert.Equal(subscriberNumber, nonGeographicPhoneNumber.SubscriberNumber);
}

[Theory]
[InlineData("9000000", "9000000")]
[InlineData("9019999", "9019999")]
[InlineData("9060000", "9060000")]
[InlineData("9069999", "9069999")]
public void Parse_Known_NonGeographicPhoneNumber_PremiumRate(string value, string subscriberNumber)
{
var parseResult = s_parser.Parse(value);
parseResult.ThrowIfFailure();

var phoneNumber = parseResult.PhoneNumber;

Assert.NotNull(phoneNumber);
Assert.IsType<NonGeographicPhoneNumber>(phoneNumber);

var nonGeographicPhoneNumber = (NonGeographicPhoneNumber)phoneNumber;
Assert.Equal(CountryInfo.Liechtenstein, nonGeographicPhoneNumber.Country);
Assert.False(nonGeographicPhoneNumber.IsFreephone);
Assert.False(nonGeographicPhoneNumber.IsMachineToMachine);
Assert.True(nonGeographicPhoneNumber.IsPremiumRate);
Assert.False(nonGeographicPhoneNumber.IsSharedCost);
Assert.Null(nonGeographicPhoneNumber.NationalDestinationCode);
Assert.Equal(subscriberNumber, nonGeographicPhoneNumber.SubscriberNumber);
}

[Theory]
[InlineData("8400000", "8400000")]
[InlineData("8499999", "8499999")]
public void Parse_Known_NonGeographicPhoneNumber_SharedCost(string value, string subscriberNumber)
{
var parseResult = s_parser.Parse(value);
parseResult.ThrowIfFailure();

var phoneNumber = parseResult.PhoneNumber;

Assert.NotNull(phoneNumber);
Assert.IsType<NonGeographicPhoneNumber>(phoneNumber);

var nonGeographicPhoneNumber = (NonGeographicPhoneNumber)phoneNumber;
Assert.Equal(CountryInfo.Liechtenstein, nonGeographicPhoneNumber.Country);
Assert.False(nonGeographicPhoneNumber.IsFreephone);
Assert.False(nonGeographicPhoneNumber.IsMachineToMachine);
Assert.False(nonGeographicPhoneNumber.IsPremiumRate);
Assert.True(nonGeographicPhoneNumber.IsSharedCost);
Assert.Null(nonGeographicPhoneNumber.NationalDestinationCode);
Assert.Equal(subscriberNumber, nonGeographicPhoneNumber.SubscriberNumber);
}
}
20 changes: 20 additions & 0 deletions test/PhoneNumbers.Tests/CountryInfo_Europe_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,26 @@ public void CountryInfo_Latvia()
Assert.Null(countryInfo.TrunkPrefix);
}

[Fact]
public void CountryInfo_Liechtenstein()
{
Assert.Same(CountryInfo.Liechtenstein, CountryInfo.Liechtenstein);

var countryInfo = CountryInfo.Liechtenstein;

Assert.False(countryInfo.AllowsLocalGeographicDialling);
Assert.Equal("423", countryInfo.CallingCode);
Assert.Equal(CountryInfo.Europe, countryInfo.Continent);
Assert.IsType<LIPhoneNumberFormatProvider>(countryInfo.FormatProvider);
Assert.False(countryInfo.IsEuropeanUnionMember);
Assert.Equal("LI", countryInfo.Iso3166Code);
Assert.Equal("Liechtenstein", countryInfo.Name);
Assert.Empty(countryInfo.NdcLengths);
Assert.Equal(new[] { 7, 9 }, countryInfo.NsnLengths);
Assert.False(countryInfo.SharesCallingCode);
Assert.Null(countryInfo.TrunkPrefix);
}

[Fact]
public void CountryInfo_Lithuania()
{
Expand Down
8 changes: 8 additions & 0 deletions test/PhoneNumbers.Tests/PhoneNumber_Parse_Europe_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,14 @@ public void Parse_Value_For_Latvia_CallingCode()
Assert.Equal(CountryInfo.Latvia, phoneNumber.Country);
}

[Fact]
public void Parse_Value_For_Liechtenstein_CallingCode()
{
var phoneNumber = PhoneNumber.Parse("+4232366488");
Assert.NotNull(phoneNumber);
Assert.Equal(CountryInfo.Liechtenstein, phoneNumber.Country);
}

[Fact]
public void Parse_Value_For_Lithuania_CallingCode()
{
Expand Down
7 changes: 7 additions & 0 deletions test/PhoneNumbers.Tests/PhoneNumber_ToString_Europe_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,13 @@ public void Kosovo_Numbers(string input, string format, string expected) =>
public void Latvia_Numbers(string input, string format, string expected) =>
Assert.Equal(expected, PhoneNumber.Parse(input).ToString(format));

[Theory]
[InlineData("+4232366488", "E.123", "+423 236 64 88")]
[InlineData("+4232366488", "N", "236 64 88")]
[InlineData("+4232366488", "RFC3966", "tel:+423-236-64-88")]
public void Liechtenstein_Numbers(string input, string format, string expected) =>
Assert.Equal(expected, PhoneNumber.Parse(input).ToString(format));

[Theory]
[InlineData("+37052105664", "E.123", "+370 5 210 5664")]
[InlineData("+37052105664", "N", "(85) 210 5664")]
Expand Down

0 comments on commit 06a8abe

Please sign in to comment.