From a98fc8a8376d4dd2464d5ab06fc3a61b3a6004a7 Mon Sep 17 00:00:00 2001 From: Trevor Pilley Date: Mon, 23 Sep 2024 15:08:17 +0100 Subject: [PATCH] Closes #701 Add support for Turkey phone numbers --- README.md | 1 + src/PhoneNumbers/CountryInfo_Asia.cs | 16 ++ src/PhoneNumbers/DataFiles/TR.txt | 92 +++++++ .../TRPhoneNumberFormatProvider.cs | 21 ++ .../Parsers/DefaultPhoneNumberParser.cs | 6 +- ...neNumberParserTests_TR_GeographicNumber.cs | 227 ++++++++++++++++++ ...eNumberParserTests_TR_MobilePhoneNumber.cs | 67 ++++++ ...ParserTests_TR_NonGeographicPhoneNumber.cs | 134 +++++++++++ .../CountryInfo_Asia_Tests.cs | 20 ++ .../PhoneNumber_Parse_Asia_Tests.cs | 8 + .../PhoneNumber_ToString_Asia_Tests.cs | 10 + .../phone-number-utilities-testgenerator | 2 +- 12 files changed, 600 insertions(+), 4 deletions(-) create mode 100644 src/PhoneNumbers/DataFiles/TR.txt create mode 100644 src/PhoneNumbers/Formatters/FormatProviders/TRPhoneNumberFormatProvider.cs create mode 100644 test/PhoneNumbers.Data.Tests/Parsers/DefaultPhoneNumberParserTests_TR_GeographicNumber.cs create mode 100644 test/PhoneNumbers.Data.Tests/Parsers/DefaultPhoneNumberParserTests_TR_MobilePhoneNumber.cs create mode 100644 test/PhoneNumbers.Data.Tests/Parsers/DefaultPhoneNumberParserTests_TR_NonGeographicPhoneNumber.cs diff --git a/README.md b/README.md index 48abceec..86cc02ee 100644 --- a/README.md +++ b/README.md @@ -189,6 +189,7 @@ Country | ISO 3166 Code | Calling Code | Trunk Prefix | Geographic | Mobi Hong Kong | HK | 852 | | | Yes | | Yes | Yes | Yes | | | Yes Macau | MO | 853 | | | Yes | | | Yes | | | | Singapore | SG | 65 | | | Yes | | | Yes | Yes | Yes | | +Turkey | TR | 90 | 0 | Yes | Yes | | Yes | Yes | Yes | Yes | | ### Europe diff --git a/src/PhoneNumbers/CountryInfo_Asia.cs b/src/PhoneNumbers/CountryInfo_Asia.cs index dbf547a3..eebac5a9 100644 --- a/src/PhoneNumbers/CountryInfo_Asia.cs +++ b/src/PhoneNumbers/CountryInfo_Asia.cs @@ -1,4 +1,5 @@ using System.Collections.ObjectModel; +using PhoneNumbers.Formatters.FormatProviders; namespace PhoneNumbers; @@ -39,4 +40,19 @@ public partial class CountryInfo Name = "Singapore", NsnLengths = new ReadOnlyCollection([8, 10, 11]), }; + + /// + /// Gets the for Turkey. + /// + public static CountryInfo Turkey { get; } = new() + { + CallingCode = "90", + Continent = Asia, + FormatProvider = TRPhoneNumberFormatProvider.Instance, + Iso3166Code = "TR", + Name = "Turkey", + NdcLengths = new ReadOnlyCollection([3, 0]), + NsnLengths = new ReadOnlyCollection([7, 10]), + TrunkPrefix = "0", + }; } diff --git a/src/PhoneNumbers/DataFiles/TR.txt b/src/PhoneNumbers/DataFiles/TR.txt new file mode 100644 index 00000000..1d6d9ebf --- /dev/null +++ b/src/PhoneNumbers/DataFiles/TR.txt @@ -0,0 +1,92 @@ +# Reference: https://www.itu.int/dms_pub/itu-t/oth/02/02/T02020000D60002PDFE.pdf +# Reference Date: 02/03/2018 +# call center numbers cannot be dialed with area code, they must be dialed with 7 digits +N|||4440000-4449999| +G|212|Istanbul (European Side)|2000000-9999999| +G|216|Istanbul (Anatolian Side)|2000000-9999999| +G|222|Eskişehir|2000000-9999999| +G|224|Bursa|2000000-9999999| +G|226|Yalova|2000000-9999999| +G|228|Bilecik|2000000-9999999| +G|232|İzmir|2000000-9999999| +G|236|Manisa|2000000-9999999| +G|242|Antalya|2000000-9999999| +G|246|Isparta|2000000-9999999| +G|248|Burdur|2000000-9999999| +G|252|Muğla|2000000-9999999| +G|256|Aydın|2000000-9999999| +G|258|Denizli|2000000-9999999| +G|262|Kocaeli|2000000-9999999| +G|264|Sakarya|2000000-9999999| +G|266|Balıkesir|2000000-9999999| +G|272|Afyon|2000000-9999999| +G|274|Kütahya|2000000-9999999| +G|276|Uşak|2000000-9999999| +G|282|Tekirdağ|2000000-9999999| +G|284|Edirne|2000000-9999999| +G|286|Çanakkale|2000000-9999999| +G|288|Kırklareli|2000000-9999999| +G|312|Ankara|2000000-9999999| +G|318|Kırıkkale|2000000-9999999| +G|322|Adana|2000000-9999999| +G|324|İçel|2000000-9999999| +G|326|Hatay|2000000-9999999| +G|328|Osmaniye|2000000-9999999| +G|332|Konya|2000000-9999999| +G|338|Karaman|2000000-9999999| +G|342|Gaziantep|2000000-9999999| +G|344|Kahramanmaraş|2000000-9999999| +G|346|Sivas|2000000-9999999| +G|348|Kilis|2000000-9999999| +G|352|Kayseri|2000000-9999999| +G|354|Yozgat|2000000-9999999| +G|356|Tokat|2000000-9999999| +G|358|Amasya|2000000-9999999| +G|362|Samsun|2000000-9999999| +G|364|Çorum|2000000-9999999| +G|366|Kastamonu|2000000-9999999| +G|368|Sinop|2000000-9999999| +G|370|Karabük|2000000-9999999| +G|372|Zonguldak|2000000-9999999| +G|374|Bolu|2000000-9999999| +G|376|Çankırı|2000000-9999999| +G|378|Bartın|2000000-9999999| +G|380|Düzce|2000000-9999999| +G|382|Aksaray|2000000-9999999| +G|384|Nevşehir|2000000-9999999| +G|386|Kırşehir|2000000-9999999| +G|388|Niğde|2000000-9999999| +G|412|Diyarbakır|2000000-9999999| +G|414|Şanlıurfa|2000000-9999999| +G|416|Adıyaman|2000000-9999999| +G|422|Malatya|2000000-9999999| +G|424|Elazığ|2000000-9999999| +G|426|Bingöl|2000000-9999999| +G|428|Tunceli|2000000-9999999| +G|432|Van|2000000-9999999| +G|434|Bitlis|2000000-9999999| +G|436|Muş|2000000-9999999| +G|438|Hakkâri|2000000-9999999| +G|442|Erzurum|2000000-9999999| +G|446|Erzincan|2000000-9999999| +G|452|Ordu|2000000-9999999| +G|454|Giresun|2000000-9999999| +G|456|Gümüşhane|2000000-9999999| +G|458|Bayburt|2000000-9999999| +G|462|Trabzon|2000000-9999999| +G|464|Rize|2000000-9999999| +G|466|Artvinv|2000000-9999999| +G|472|Ağrı|2000000-9999999| +G|474|Kars|2000000-9999999| +G|476|Iğdır|2000000-9999999| +G|478|Ardahan|2000000-9999999| +G|482|Mardin|2000000-9999999| +G|484|Siirt|2000000-9999999| +G|486|Şırnak|2000000-9999999| +G|488|Batman|2000000-9999999| +M|501,505-507,530-549,551-555,559,592||0000000-9999999| +N|510,516,524||2000000-9999999| +N|800||0000000-9999999|F +N|811-812||0000000-9999999| +M|850||0000000-9999999|V +N|888,898,900||0000000-9999999|R diff --git a/src/PhoneNumbers/Formatters/FormatProviders/TRPhoneNumberFormatProvider.cs b/src/PhoneNumbers/Formatters/FormatProviders/TRPhoneNumberFormatProvider.cs new file mode 100644 index 00000000..4a31d96b --- /dev/null +++ b/src/PhoneNumbers/Formatters/FormatProviders/TRPhoneNumberFormatProvider.cs @@ -0,0 +1,21 @@ +namespace PhoneNumbers.Formatters.FormatProviders; + +/// +/// A for Turkey numbers. +/// +internal sealed class TRPhoneNumberFormatProvider : ComplexPhoneNumberFormatProvider +{ + private TRPhoneNumberFormatProvider() + { + } + + internal static PhoneNumberFormatProvider Instance { get; } = new TRPhoneNumberFormatProvider(); + + protected override string ProvideFormat(PhoneNumber phoneNumber, bool international) => + phoneNumber.NationalSignificantNumber.Length switch + { + 7 => international ? "### ## ##" : "(0###) ## ##", + 10 => international ? "### ### ## ##" : "(0###) ### ## ##", + _ => base.ProvideFormat(phoneNumber, international), + }; +} diff --git a/src/PhoneNumbers/Parsers/DefaultPhoneNumberParser.cs b/src/PhoneNumbers/Parsers/DefaultPhoneNumberParser.cs index 62e6d417..fec2183c 100644 --- a/src/PhoneNumbers/Parsers/DefaultPhoneNumberParser.cs +++ b/src/PhoneNumbers/Parsers/DefaultPhoneNumberParser.cs @@ -50,12 +50,12 @@ protected virtual (string? NationalDestinationCode, string? SubscriberNumber, Co continue; } - ndc = nsnValue.Substring(0, len); - sn = nsnValue.Substring(ndc.Length); + ndc = len > 0 ? nsnValue.Substring(0, len) : null; + sn = ndc is not null ? nsnValue.Substring(ndc.Length) : nsnValue; countryNumber = CountryNumbers .FirstOrDefault(x => - x.NationalDestinationCodeRanges!.Any(x => x.Contains(ndc)) && + (ndc is null || x.NationalDestinationCodeRanges?.Any(x => x.Contains(ndc)) == true) && x.SubscriberNumberRanges.Any(x => x.Contains(sn))); if (countryNumber is not null) diff --git a/test/PhoneNumbers.Data.Tests/Parsers/DefaultPhoneNumberParserTests_TR_GeographicNumber.cs b/test/PhoneNumbers.Data.Tests/Parsers/DefaultPhoneNumberParserTests_TR_GeographicNumber.cs new file mode 100644 index 00000000..554cd2a7 --- /dev/null +++ b/test/PhoneNumbers.Data.Tests/Parsers/DefaultPhoneNumberParserTests_TR_GeographicNumber.cs @@ -0,0 +1,227 @@ +namespace PhoneNumbers.Tests.Parsers; + +/// +/// Contains unit tests for the class for Turkey s. +/// +public class DefaultPhoneNumberParserTests_TR_GeographicNumber +{ + private static readonly PhoneNumberParser s_parser = DefaultPhoneNumberParser.Create(CountryInfo.Turkey); + + [Theory] + [InlineData("02122000000", "212", "2000000", "Istanbul (European Side)")] + [InlineData("02129999999", "212", "9999999", "Istanbul (European Side)")] + [InlineData("02162000000", "216", "2000000", "Istanbul (Anatolian Side)")] + [InlineData("02169999999", "216", "9999999", "Istanbul (Anatolian Side)")] + [InlineData("02222000000", "222", "2000000", "Eskişehir")] + [InlineData("02229999999", "222", "9999999", "Eskişehir")] + [InlineData("02242000000", "224", "2000000", "Bursa")] + [InlineData("02249999999", "224", "9999999", "Bursa")] + [InlineData("02262000000", "226", "2000000", "Yalova")] + [InlineData("02269999999", "226", "9999999", "Yalova")] + [InlineData("02282000000", "228", "2000000", "Bilecik")] + [InlineData("02289999999", "228", "9999999", "Bilecik")] + [InlineData("02322000000", "232", "2000000", "İzmir")] + [InlineData("02329999999", "232", "9999999", "İzmir")] + [InlineData("02362000000", "236", "2000000", "Manisa")] + [InlineData("02369999999", "236", "9999999", "Manisa")] + [InlineData("02422000000", "242", "2000000", "Antalya")] + [InlineData("02429999999", "242", "9999999", "Antalya")] + [InlineData("02462000000", "246", "2000000", "Isparta")] + [InlineData("02469999999", "246", "9999999", "Isparta")] + [InlineData("02482000000", "248", "2000000", "Burdur")] + [InlineData("02489999999", "248", "9999999", "Burdur")] + [InlineData("02522000000", "252", "2000000", "Muğla")] + [InlineData("02529999999", "252", "9999999", "Muğla")] + [InlineData("02562000000", "256", "2000000", "Aydın")] + [InlineData("02569999999", "256", "9999999", "Aydın")] + [InlineData("02582000000", "258", "2000000", "Denizli")] + [InlineData("02589999999", "258", "9999999", "Denizli")] + [InlineData("02622000000", "262", "2000000", "Kocaeli")] + [InlineData("02629999999", "262", "9999999", "Kocaeli")] + [InlineData("02642000000", "264", "2000000", "Sakarya")] + [InlineData("02649999999", "264", "9999999", "Sakarya")] + [InlineData("02662000000", "266", "2000000", "Balıkesir")] + [InlineData("02669999999", "266", "9999999", "Balıkesir")] + [InlineData("02722000000", "272", "2000000", "Afyon")] + [InlineData("02729999999", "272", "9999999", "Afyon")] + [InlineData("02742000000", "274", "2000000", "Kütahya")] + [InlineData("02749999999", "274", "9999999", "Kütahya")] + [InlineData("02762000000", "276", "2000000", "Uşak")] + [InlineData("02769999999", "276", "9999999", "Uşak")] + [InlineData("02822000000", "282", "2000000", "Tekirdağ")] + [InlineData("02829999999", "282", "9999999", "Tekirdağ")] + [InlineData("02842000000", "284", "2000000", "Edirne")] + [InlineData("02849999999", "284", "9999999", "Edirne")] + [InlineData("02862000000", "286", "2000000", "Çanakkale")] + [InlineData("02869999999", "286", "9999999", "Çanakkale")] + [InlineData("02882000000", "288", "2000000", "Kırklareli")] + [InlineData("02889999999", "288", "9999999", "Kırklareli")] + public void Parse_Known_GeographicPhoneNumber_2XX_NationalDestinationCode(string value, string NationalDestinationCode, string subscriberNumber, string geographicArea) + { + var parseResult = s_parser.Parse(value); + parseResult.ThrowIfFailure(); + + var phoneNumber = parseResult.PhoneNumber; + + Assert.NotNull(phoneNumber); + Assert.IsType(phoneNumber); + + var geographicPhoneNumber = (GeographicPhoneNumber)phoneNumber; + Assert.Equal(CountryInfo.Turkey, geographicPhoneNumber.Country); + Assert.Equal(geographicArea, geographicPhoneNumber.GeographicArea); + Assert.Equal(NationalDestinationCode, geographicPhoneNumber.NationalDestinationCode); + Assert.Equal(subscriberNumber, geographicPhoneNumber.SubscriberNumber); + } + + [Theory] + [InlineData("03122000000", "312", "2000000", "Ankara")] + [InlineData("03129999999", "312", "9999999", "Ankara")] + [InlineData("03182000000", "318", "2000000", "Kırıkkale")] + [InlineData("03189999999", "318", "9999999", "Kırıkkale")] + [InlineData("03222000000", "322", "2000000", "Adana")] + [InlineData("03229999999", "322", "9999999", "Adana")] + [InlineData("03242000000", "324", "2000000", "İçel")] + [InlineData("03249999999", "324", "9999999", "İçel")] + [InlineData("03262000000", "326", "2000000", "Hatay")] + [InlineData("03269999999", "326", "9999999", "Hatay")] + [InlineData("03282000000", "328", "2000000", "Osmaniye")] + [InlineData("03289999999", "328", "9999999", "Osmaniye")] + [InlineData("03322000000", "332", "2000000", "Konya")] + [InlineData("03329999999", "332", "9999999", "Konya")] + [InlineData("03382000000", "338", "2000000", "Karaman")] + [InlineData("03389999999", "338", "9999999", "Karaman")] + [InlineData("03422000000", "342", "2000000", "Gaziantep")] + [InlineData("03429999999", "342", "9999999", "Gaziantep")] + [InlineData("03442000000", "344", "2000000", "Kahramanmaraş")] + [InlineData("03449999999", "344", "9999999", "Kahramanmaraş")] + [InlineData("03462000000", "346", "2000000", "Sivas")] + [InlineData("03469999999", "346", "9999999", "Sivas")] + [InlineData("03482000000", "348", "2000000", "Kilis")] + [InlineData("03489999999", "348", "9999999", "Kilis")] + [InlineData("03522000000", "352", "2000000", "Kayseri")] + [InlineData("03529999999", "352", "9999999", "Kayseri")] + [InlineData("03542000000", "354", "2000000", "Yozgat")] + [InlineData("03549999999", "354", "9999999", "Yozgat")] + [InlineData("03562000000", "356", "2000000", "Tokat")] + [InlineData("03569999999", "356", "9999999", "Tokat")] + [InlineData("03582000000", "358", "2000000", "Amasya")] + [InlineData("03589999999", "358", "9999999", "Amasya")] + [InlineData("03622000000", "362", "2000000", "Samsun")] + [InlineData("03629999999", "362", "9999999", "Samsun")] + [InlineData("03642000000", "364", "2000000", "Çorum")] + [InlineData("03649999999", "364", "9999999", "Çorum")] + [InlineData("03662000000", "366", "2000000", "Kastamonu")] + [InlineData("03669999999", "366", "9999999", "Kastamonu")] + [InlineData("03682000000", "368", "2000000", "Sinop")] + [InlineData("03689999999", "368", "9999999", "Sinop")] + [InlineData("03702000000", "370", "2000000", "Karabük")] + [InlineData("03709999999", "370", "9999999", "Karabük")] + [InlineData("03722000000", "372", "2000000", "Zonguldak")] + [InlineData("03729999999", "372", "9999999", "Zonguldak")] + [InlineData("03742000000", "374", "2000000", "Bolu")] + [InlineData("03749999999", "374", "9999999", "Bolu")] + [InlineData("03762000000", "376", "2000000", "Çankırı")] + [InlineData("03769999999", "376", "9999999", "Çankırı")] + [InlineData("03782000000", "378", "2000000", "Bartın")] + [InlineData("03789999999", "378", "9999999", "Bartın")] + [InlineData("03802000000", "380", "2000000", "Düzce")] + [InlineData("03809999999", "380", "9999999", "Düzce")] + [InlineData("03822000000", "382", "2000000", "Aksaray")] + [InlineData("03829999999", "382", "9999999", "Aksaray")] + [InlineData("03842000000", "384", "2000000", "Nevşehir")] + [InlineData("03849999999", "384", "9999999", "Nevşehir")] + [InlineData("03862000000", "386", "2000000", "Kırşehir")] + [InlineData("03869999999", "386", "9999999", "Kırşehir")] + [InlineData("03882000000", "388", "2000000", "Niğde")] + [InlineData("03889999999", "388", "9999999", "Niğde")] + public void Parse_Known_GeographicPhoneNumber_3XX_NationalDestinationCode(string value, string NationalDestinationCode, string subscriberNumber, string geographicArea) + { + var parseResult = s_parser.Parse(value); + parseResult.ThrowIfFailure(); + + var phoneNumber = parseResult.PhoneNumber; + + Assert.NotNull(phoneNumber); + Assert.IsType(phoneNumber); + + var geographicPhoneNumber = (GeographicPhoneNumber)phoneNumber; + Assert.Equal(CountryInfo.Turkey, geographicPhoneNumber.Country); + Assert.Equal(geographicArea, geographicPhoneNumber.GeographicArea); + Assert.Equal(NationalDestinationCode, geographicPhoneNumber.NationalDestinationCode); + Assert.Equal(subscriberNumber, geographicPhoneNumber.SubscriberNumber); + } + + [Theory] + [InlineData("04122000000", "412", "2000000", "Diyarbakır")] + [InlineData("04129999999", "412", "9999999", "Diyarbakır")] + [InlineData("04142000000", "414", "2000000", "Şanlıurfa")] + [InlineData("04149999999", "414", "9999999", "Şanlıurfa")] + [InlineData("04162000000", "416", "2000000", "Adıyaman")] + [InlineData("04169999999", "416", "9999999", "Adıyaman")] + [InlineData("04222000000", "422", "2000000", "Malatya")] + [InlineData("04229999999", "422", "9999999", "Malatya")] + [InlineData("04242000000", "424", "2000000", "Elazığ")] + [InlineData("04249999999", "424", "9999999", "Elazığ")] + [InlineData("04262000000", "426", "2000000", "Bingöl")] + [InlineData("04269999999", "426", "9999999", "Bingöl")] + [InlineData("04282000000", "428", "2000000", "Tunceli")] + [InlineData("04289999999", "428", "9999999", "Tunceli")] + [InlineData("04322000000", "432", "2000000", "Van")] + [InlineData("04329999999", "432", "9999999", "Van")] + [InlineData("04342000000", "434", "2000000", "Bitlis")] + [InlineData("04349999999", "434", "9999999", "Bitlis")] + [InlineData("04362000000", "436", "2000000", "Muş")] + [InlineData("04369999999", "436", "9999999", "Muş")] + [InlineData("04382000000", "438", "2000000", "Hakkâri")] + [InlineData("04389999999", "438", "9999999", "Hakkâri")] + [InlineData("04422000000", "442", "2000000", "Erzurum")] + [InlineData("04429999999", "442", "9999999", "Erzurum")] + [InlineData("04462000000", "446", "2000000", "Erzincan")] + [InlineData("04469999999", "446", "9999999", "Erzincan")] + [InlineData("04522000000", "452", "2000000", "Ordu")] + [InlineData("04529999999", "452", "9999999", "Ordu")] + [InlineData("04542000000", "454", "2000000", "Giresun")] + [InlineData("04549999999", "454", "9999999", "Giresun")] + [InlineData("04562000000", "456", "2000000", "Gümüşhane")] + [InlineData("04569999999", "456", "9999999", "Gümüşhane")] + [InlineData("04582000000", "458", "2000000", "Bayburt")] + [InlineData("04589999999", "458", "9999999", "Bayburt")] + [InlineData("04622000000", "462", "2000000", "Trabzon")] + [InlineData("04629999999", "462", "9999999", "Trabzon")] + [InlineData("04642000000", "464", "2000000", "Rize")] + [InlineData("04649999999", "464", "9999999", "Rize")] + [InlineData("04662000000", "466", "2000000", "Artvinv")] + [InlineData("04669999999", "466", "9999999", "Artvinv")] + [InlineData("04722000000", "472", "2000000", "Ağrı")] + [InlineData("04729999999", "472", "9999999", "Ağrı")] + [InlineData("04742000000", "474", "2000000", "Kars")] + [InlineData("04749999999", "474", "9999999", "Kars")] + [InlineData("04762000000", "476", "2000000", "Iğdır")] + [InlineData("04769999999", "476", "9999999", "Iğdır")] + [InlineData("04782000000", "478", "2000000", "Ardahan")] + [InlineData("04789999999", "478", "9999999", "Ardahan")] + [InlineData("04822000000", "482", "2000000", "Mardin")] + [InlineData("04829999999", "482", "9999999", "Mardin")] + [InlineData("04842000000", "484", "2000000", "Siirt")] + [InlineData("04849999999", "484", "9999999", "Siirt")] + [InlineData("04862000000", "486", "2000000", "Şırnak")] + [InlineData("04869999999", "486", "9999999", "Şırnak")] + [InlineData("04882000000", "488", "2000000", "Batman")] + [InlineData("04889999999", "488", "9999999", "Batman")] + public void Parse_Known_GeographicPhoneNumber_4XX_NationalDestinationCode(string value, string NationalDestinationCode, string subscriberNumber, string geographicArea) + { + var parseResult = s_parser.Parse(value); + parseResult.ThrowIfFailure(); + + var phoneNumber = parseResult.PhoneNumber; + + Assert.NotNull(phoneNumber); + Assert.IsType(phoneNumber); + + var geographicPhoneNumber = (GeographicPhoneNumber)phoneNumber; + Assert.Equal(CountryInfo.Turkey, geographicPhoneNumber.Country); + Assert.Equal(geographicArea, geographicPhoneNumber.GeographicArea); + Assert.Equal(NationalDestinationCode, geographicPhoneNumber.NationalDestinationCode); + Assert.Equal(subscriberNumber, geographicPhoneNumber.SubscriberNumber); + } +} diff --git a/test/PhoneNumbers.Data.Tests/Parsers/DefaultPhoneNumberParserTests_TR_MobilePhoneNumber.cs b/test/PhoneNumbers.Data.Tests/Parsers/DefaultPhoneNumberParserTests_TR_MobilePhoneNumber.cs new file mode 100644 index 00000000..5d91c5d6 --- /dev/null +++ b/test/PhoneNumbers.Data.Tests/Parsers/DefaultPhoneNumberParserTests_TR_MobilePhoneNumber.cs @@ -0,0 +1,67 @@ +namespace PhoneNumbers.Tests.Parsers; + +/// +/// Contains unit tests for the class for Turkey s. +/// +public class DefaultPhoneNumberParserTests_TR_MobilePhoneNumber +{ + private static readonly PhoneNumberParser s_parser = DefaultPhoneNumberParser.Create(CountryInfo.Turkey); + + [Theory] + [InlineData("05010000000", "501", "0000000")] + [InlineData("05019999999", "501", "9999999")] + [InlineData("05050000000", "505", "0000000")] + [InlineData("05059999999", "505", "9999999")] + [InlineData("05070000000", "507", "0000000")] + [InlineData("05079999999", "507", "9999999")] + [InlineData("05300000000", "530", "0000000")] + [InlineData("05309999999", "530", "9999999")] + [InlineData("05490000000", "549", "0000000")] + [InlineData("05499999999", "549", "9999999")] + [InlineData("05510000000", "551", "0000000")] + [InlineData("05519999999", "551", "9999999")] + [InlineData("05550000000", "555", "0000000")] + [InlineData("05559999999", "555", "9999999")] + [InlineData("05590000000", "559", "0000000")] + [InlineData("05599999999", "559", "9999999")] + [InlineData("05920000000", "592", "0000000")] + [InlineData("05929999999", "592", "9999999")] + public void Parse_Known_MobilePhoneNumber(string value, string NationalDestinationCode, string subscriberNumber) + { + var parseResult = s_parser.Parse(value); + parseResult.ThrowIfFailure(); + + var phoneNumber = parseResult.PhoneNumber; + + Assert.NotNull(phoneNumber); + Assert.IsType(phoneNumber); + + var mobilePhoneNumber = (MobilePhoneNumber)phoneNumber; + Assert.Equal(CountryInfo.Turkey, mobilePhoneNumber.Country); + Assert.False(mobilePhoneNumber.IsPager); + Assert.False(mobilePhoneNumber.IsVirtual); + Assert.Equal(NationalDestinationCode, mobilePhoneNumber.NationalDestinationCode); + Assert.Equal(subscriberNumber, mobilePhoneNumber.SubscriberNumber); + } + + [Theory] + [InlineData("08500000000", "850", "0000000")] + [InlineData("08509999999", "850", "9999999")] + public void Parse_Known_MobilePhoneNumber_Virtual(string value, string NationalDestinationCode, string subscriberNumber) + { + var parseResult = s_parser.Parse(value); + parseResult.ThrowIfFailure(); + + var phoneNumber = parseResult.PhoneNumber; + + Assert.NotNull(phoneNumber); + Assert.IsType(phoneNumber); + + var mobilePhoneNumber = (MobilePhoneNumber)phoneNumber; + Assert.Equal(CountryInfo.Turkey, mobilePhoneNumber.Country); + Assert.False(mobilePhoneNumber.IsPager); + Assert.True(mobilePhoneNumber.IsVirtual); + Assert.Equal(NationalDestinationCode, mobilePhoneNumber.NationalDestinationCode); + Assert.Equal(subscriberNumber, mobilePhoneNumber.SubscriberNumber); + } +} diff --git a/test/PhoneNumbers.Data.Tests/Parsers/DefaultPhoneNumberParserTests_TR_NonGeographicPhoneNumber.cs b/test/PhoneNumbers.Data.Tests/Parsers/DefaultPhoneNumberParserTests_TR_NonGeographicPhoneNumber.cs new file mode 100644 index 00000000..1dee8987 --- /dev/null +++ b/test/PhoneNumbers.Data.Tests/Parsers/DefaultPhoneNumberParserTests_TR_NonGeographicPhoneNumber.cs @@ -0,0 +1,134 @@ +namespace PhoneNumbers.Tests.Parsers; + +/// +/// Contains unit tests for the class for Turkey s. +/// +public class DefaultPhoneNumberParserTests_TR_NonGeographicPhoneNumber +{ + private static readonly PhoneNumberParser s_parser = DefaultPhoneNumberParser.Create(CountryInfo.Turkey); + + [Theory] + [InlineData("05102000000", "510", "2000000")] + [InlineData("05109999999", "510", "9999999")] + [InlineData("05162000000", "516", "2000000")] + [InlineData("05169999999", "516", "9999999")] + [InlineData("05242000000", "524", "2000000")] + [InlineData("05249999999", "524", "9999999")] + public void Parse_Known_NonGeographicPhoneNumber_5XX_NationalDestinationCode(string value, string NationalDestinationCode, string subscriberNumber) + { + var parseResult = s_parser.Parse(value); + parseResult.ThrowIfFailure(); + + var phoneNumber = parseResult.PhoneNumber; + + Assert.NotNull(phoneNumber); + Assert.IsType(phoneNumber); + + var nonGeographicPhoneNumber = (NonGeographicPhoneNumber)phoneNumber; + Assert.Equal(CountryInfo.Turkey, nonGeographicPhoneNumber.Country); + Assert.False(nonGeographicPhoneNumber.IsFreephone); + Assert.False(nonGeographicPhoneNumber.IsMachineToMachine); + Assert.False(nonGeographicPhoneNumber.IsPremiumRate); + Assert.False(nonGeographicPhoneNumber.IsSharedCost); + Assert.Equal(NationalDestinationCode, nonGeographicPhoneNumber.NationalDestinationCode); + Assert.Equal(subscriberNumber, nonGeographicPhoneNumber.SubscriberNumber); + } + + [Theory] + [InlineData("08110000000", "811", "0000000")] + [InlineData("08119999999", "811", "9999999")] + [InlineData("08120000000", "812", "0000000")] + [InlineData("08129999999", "812", "9999999")] + public void Parse_Known_NonGeographicPhoneNumber_8XX_NationalDestinationCode(string value, string NationalDestinationCode, string subscriberNumber) + { + var parseResult = s_parser.Parse(value); + parseResult.ThrowIfFailure(); + + var phoneNumber = parseResult.PhoneNumber; + + Assert.NotNull(phoneNumber); + Assert.IsType(phoneNumber); + + var nonGeographicPhoneNumber = (NonGeographicPhoneNumber)phoneNumber; + Assert.Equal(CountryInfo.Turkey, nonGeographicPhoneNumber.Country); + Assert.False(nonGeographicPhoneNumber.IsFreephone); + Assert.False(nonGeographicPhoneNumber.IsMachineToMachine); + Assert.False(nonGeographicPhoneNumber.IsPremiumRate); + Assert.False(nonGeographicPhoneNumber.IsSharedCost); + Assert.Equal(NationalDestinationCode, nonGeographicPhoneNumber.NationalDestinationCode); + Assert.Equal(subscriberNumber, nonGeographicPhoneNumber.SubscriberNumber); + } + + [Theory] + [InlineData("04440000", "4440000")] + [InlineData("04449999", "4449999")] + 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(phoneNumber); + + var nonGeographicPhoneNumber = (NonGeographicPhoneNumber)phoneNumber; + Assert.Equal(CountryInfo.Turkey, 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("08000000000", "800", "0000000")] + [InlineData("08009999999", "800", "9999999")] + public void Parse_Known_NonGeographicPhoneNumber_Freephone(string value, string NationalDestinationCode, string subscriberNumber) + { + var parseResult = s_parser.Parse(value); + parseResult.ThrowIfFailure(); + + var phoneNumber = parseResult.PhoneNumber; + + Assert.NotNull(phoneNumber); + Assert.IsType(phoneNumber); + + var nonGeographicPhoneNumber = (NonGeographicPhoneNumber)phoneNumber; + Assert.Equal(CountryInfo.Turkey, nonGeographicPhoneNumber.Country); + Assert.True(nonGeographicPhoneNumber.IsFreephone); + Assert.False(nonGeographicPhoneNumber.IsMachineToMachine); + Assert.False(nonGeographicPhoneNumber.IsPremiumRate); + Assert.False(nonGeographicPhoneNumber.IsSharedCost); + Assert.Equal(NationalDestinationCode, nonGeographicPhoneNumber.NationalDestinationCode); + Assert.Equal(subscriberNumber, nonGeographicPhoneNumber.SubscriberNumber); + } + + [Theory] + [InlineData("08880000000", "888", "0000000")] + [InlineData("08889999999", "888", "9999999")] + [InlineData("08980000000", "898", "0000000")] + [InlineData("08989999999", "898", "9999999")] + [InlineData("09000000000", "900", "0000000")] + [InlineData("09009999999", "900", "9999999")] + public void Parse_Known_NonGeographicPhoneNumber_PremiumRate(string value, string NationalDestinationCode, string subscriberNumber) + { + var parseResult = s_parser.Parse(value); + parseResult.ThrowIfFailure(); + + var phoneNumber = parseResult.PhoneNumber; + + Assert.NotNull(phoneNumber); + Assert.IsType(phoneNumber); + + var nonGeographicPhoneNumber = (NonGeographicPhoneNumber)phoneNumber; + Assert.Equal(CountryInfo.Turkey, nonGeographicPhoneNumber.Country); + Assert.False(nonGeographicPhoneNumber.IsFreephone); + Assert.False(nonGeographicPhoneNumber.IsMachineToMachine); + Assert.True(nonGeographicPhoneNumber.IsPremiumRate); + Assert.False(nonGeographicPhoneNumber.IsSharedCost); + Assert.Equal(NationalDestinationCode, nonGeographicPhoneNumber.NationalDestinationCode); + Assert.Equal(subscriberNumber, nonGeographicPhoneNumber.SubscriberNumber); + } +} diff --git a/test/PhoneNumbers.Tests/CountryInfo_Asia_Tests.cs b/test/PhoneNumbers.Tests/CountryInfo_Asia_Tests.cs index 84157ab8..3013a66d 100644 --- a/test/PhoneNumbers.Tests/CountryInfo_Asia_Tests.cs +++ b/test/PhoneNumbers.Tests/CountryInfo_Asia_Tests.cs @@ -63,4 +63,24 @@ public void CountryInfo_Singapore() Assert.False(countryInfo.SharesCallingCode); Assert.Null(countryInfo.TrunkPrefix); } + + [Fact] + public void CountryInfo_Turkey() + { + Assert.Same(CountryInfo.Turkey, CountryInfo.Turkey); + + var countryInfo = CountryInfo.Turkey; + + Assert.False(countryInfo.AllowsLocalGeographicDialling); + Assert.Equal("90", countryInfo.CallingCode); + Assert.Equal(CountryInfo.Asia, countryInfo.Continent); + Assert.IsType(countryInfo.FormatProvider); + Assert.False(countryInfo.IsEuropeanUnionMember); + Assert.Equal("TR", countryInfo.Iso3166Code); + Assert.Equal("Turkey", countryInfo.Name); + Assert.Equal(new[] { 3, 0 }, countryInfo.NdcLengths); + Assert.Equal(new[] { 7, 10 }, countryInfo.NsnLengths); + Assert.False(countryInfo.SharesCallingCode); + Assert.Equal("0", countryInfo.TrunkPrefix); + } } diff --git a/test/PhoneNumbers.Tests/PhoneNumber_Parse_Asia_Tests.cs b/test/PhoneNumbers.Tests/PhoneNumber_Parse_Asia_Tests.cs index 33bf4907..1ca5b4ea 100644 --- a/test/PhoneNumbers.Tests/PhoneNumber_Parse_Asia_Tests.cs +++ b/test/PhoneNumbers.Tests/PhoneNumber_Parse_Asia_Tests.cs @@ -25,4 +25,12 @@ public void Parse_Value_For_Singapore_CallingCode() Assert.NotNull(phoneNumber); Assert.Equal(CountryInfo.Singapore, phoneNumber.Country); } + + [Fact] + public void Parse_Value_For_Turkey_CallingCode() + { + var phoneNumber = PhoneNumber.Parse("+903122947200"); + Assert.NotNull(phoneNumber); + Assert.Equal(CountryInfo.Turkey, phoneNumber.Country); + } } diff --git a/test/PhoneNumbers.Tests/PhoneNumber_ToString_Asia_Tests.cs b/test/PhoneNumbers.Tests/PhoneNumber_ToString_Asia_Tests.cs index b3fb27c6..19d872dc 100644 --- a/test/PhoneNumbers.Tests/PhoneNumber_ToString_Asia_Tests.cs +++ b/test/PhoneNumbers.Tests/PhoneNumber_ToString_Asia_Tests.cs @@ -22,4 +22,14 @@ public void Macau_Numbers(string input, string format, string expected) => [InlineData("+6563773800", "RFC3966", "tel:+65-6377-3800")] public void Singapore_Numbers(string input, string format, string expected) => Assert.Equal(expected, PhoneNumber.Parse(input).ToString(format)); + + [Theory] + [InlineData("+904441234", "E.123", "+90 444 12 34")] + [InlineData("+903122947200", "E.123", "+90 312 294 72 00")] + [InlineData("+904441234", "N", "(0444) 12 34")] + [InlineData("+903122947200", "N", "(0312) 294 72 00")] + [InlineData("+904441234", "RFC3966", "tel:+90-444-12-34")] + [InlineData("+903122947200", "RFC3966", "tel:+90-312-294-72-00")] + public void Turkey_Numbers(string input, string format, string expected) => + Assert.Equal(expected, PhoneNumber.Parse(input).ToString(format)); } diff --git a/utilities/phone-number-utilities-testgenerator b/utilities/phone-number-utilities-testgenerator index db05a382..08e40f47 160000 --- a/utilities/phone-number-utilities-testgenerator +++ b/utilities/phone-number-utilities-testgenerator @@ -1 +1 @@ -Subproject commit db05a3829afa9baf5e7797326c212b61dab9d22c +Subproject commit 08e40f4714a6721cc00a031933a0d8f46898ca55