diff --git a/README.md b/README.md index 27cae91..aaeb7d9 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,80 @@ The library is available on [NuGet](https://www.nuget.org/packages/ItalianToolki - [x] Formal validation (EXPERIMENTAL) - [x] Check character calculation (EXPERIMENTAL) - [ ] Transports - - [ ] Car plates validation (pre 1994) - - [ ] Car plates validation (post 1994) + - [ ] Car plates validation + - [ ] Car plates (pre 1994) + - [x] Car plates (post 1994) + - [x] Trailers + - [x] Motorcycles and Motorbikes plates validation + - [x] Motorcycles (mopeds, three-wheelers, motor-tractors and light quadricycles with an engine capacity of less than 50 cm³) + - [x] Motorbikes (motor vehicles and quadrycycles with an engine capacity of more than 50 cm³) - (Warning: old provinces codes check is missing) + - [ ] Special vehicles plates validation + - [x] Carabineers + - [ ] Civil Protection Department + - [x] Cars + - [ ] Trailers used as emergency shelter + - [x] Civil Protection - Aosta Valley + - [x] Civil Protection - Bolzano + - [x] Civil Protection - Friuli + - [X] Civil Protection - Trento + - [x] Coast Guard - Port Authorities + - [x] Department representative vehicles + - [x] Cars + - [x] Buses and heavy vehicles + - [x] Motorbikes + - [x] Trailers + - [x] Diplomatic, consular corps and United Nations vehicles + - [x] Consolar corps + - [x] Diplomatic corps + - [x] United Nations (service vehicles) + - [x] United Nations (staff personal vehicles) + - [x] United Nations (vehicles in transit through Italy) + - [x] Foreign Excursionists (EE) temporary plates + - [x] Finance Guards + - [x] Cars + - [x] Motorbikes + - [x] Trailers + - [x] Fire Fighters + - [x] Cars + - [x] Trailers + - [x] Test plates + - [x] Fire Fighters - Bolzano + - [x] Fire Fighters - Trento + - [x] Forestry Corps + - [x] Italian Forestry Corps + - [x] Forestry Corps - Aosta + - [x] Forestry Corps - Bolzano + - [x] Forestry Corps - Friuli + - [x] Forestry Corps - Sardinia (all provinces) + - [x] Forestry Corps - Sicily (all provinces) + - [x] Forestry Corps - Trento + - [x] Italian Red Cross + - [x] Italian Red Cross (cars and ambulances) + - [x] Italian Red Cross (motorcycles, motorbikes, trailers and roulottes) + - [x] Italian Air Force + - [x] Cars + - [x] Motorbikes + - [x] Italian Army + - [x] Cars + - [x] Trailers + - [x] Tanks and armored vehicles + - [x] Historical vehicles re-registered + - [x] Italian Navy + - [x] Cars + - [x] Trailers + - [x] Local Police + - [x] Cars + - [x] Motorcycles + - [x] Motorbikes + - [x] Penitentiary Police + - [ ] Temporary plates for vehicles in transit + - [x] Test plates + - [x] Sovereign Military Order of Malta + - [x] Cars + - [x] Motorbykes + - [x] State Police + - [x] Cars + - [x] Special cars (e.g. Lamborghini Huracan for organs transport) - [ ] Places - [ ] Regions - [ ] Provinces diff --git a/src/ItalianToolkit.Tests/Transports/PlatesHelperTests.cs b/src/ItalianToolkit.Tests/Transports/PlatesHelperTests.cs new file mode 100644 index 0000000..53618b7 --- /dev/null +++ b/src/ItalianToolkit.Tests/Transports/PlatesHelperTests.cs @@ -0,0 +1,2330 @@ +using System; +using System.Linq; +using ItalianToolkit.Transports; +using ItalianToolkit.Transports.Models; +using NUnit.Framework; + +namespace ItalianToolkit.Tests.Transports +{ + internal class PlatesHelperTests + { + private PlatesIdentifier _platesHelper; + + [OneTimeSetUp] + public void OneTimeSetup() + { + _platesHelper = new PlatesIdentifier(); + } + + [SetUp] + public void Setup() + { + } + + [Test, Category("Common vehicles")] + public void CarPlateShouldBeValidated() + { + var validCarPlates = new[] + { + "AA 123BB", + "AA999 EE", + "dK 010 DB", + "LL 333BA", + "ll333 ba", + "LL333bA", + "Ll333bA" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.Car, result.Items.First().Type); + } + } + + [Test, Category("Common vehicles")] + public void CarPlateShouldFailValidation() + { + var notValidCarPlates = new[] + { + "A123BB", + "AA999E", + "$$123EL", + "OA555AA", + "AA333IA", + "AU333EE", + "AB 333 IE", + }; + + foreach (var plate in notValidCarPlates) + + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsFalse(result.IsFound); + Assert.AreEqual(0, result.Items.Count); + } + } + + [Test, Category("Common vehicles")] + public void MotorcyclesPlateShouldBeValidated() + { + // Ciclomotori motocarri e mototrattori di cilindrata inferiore a 50 cm³, e quadricicli leggeri + var validCarPlates = new[] + { + "X 92345", + "BX9 83C", + "Bx 98dc", + "Bx98xc", + "dd98lc", + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.Motorcycle, result.Items.First().Type); + } + } + + [Test, Category("Common vehicles")] + public void MotorbikesPlateShouldBeValidated() + { + // Motocicli, motoveicoli, motocarri, mototrattori e quadricicli di cilindrata superiore a 50 cm³ + var validMotorbikePlates = new[] + { + "AX 92345", + "BX 12345", + " Bx 4 5 6 7 8", + "LP 98 87 1" + }; + + foreach (var plate in validMotorbikePlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.Motorbike, result.Items.First().Type); + } + } + + [Test, Category("Common vehicles")] + public void MotorbikePlateShouldFailValidation() + { + // TODO: add filter for old provinces codes + var notValidMotorbikePlates = new string[] + { + //"AN 12345", + //"MC 87653", + //"RM 43121", + //"AP 09841", + //"PU 123 45", + //"PS 12678" + }; + + foreach (var plate in notValidMotorbikePlates) + + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsFalse(result.IsFound); + Assert.AreEqual(0, result.Items.Count); + } + } + + [Test, Category("Common vehicles")] + public void TrailersPlateShouldBeValidated() + { + var validPlates = new[] + { + "XA 123 AA", + "XA999 EE", + "xK 010 DB", + "xL 333BA", + "xl333 ba", + "XL333bA", + "xl333bA" + }; + + foreach (var plate in validPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.Trailer, result.Items.First().Type); + } + } + + [Test, Category("Armed Forces")] + public void CarabineersPlateShouldBeValidated() + { + // Arma dei Carabinieri plates -> CC AA 000 + + var validCarPlates = new[] + { + "CC AH 500", + "CC AH 501", + "CC AH 700", + "cc bg 666", + "ccea637", + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.Carabineers)); + } + } + + [Test, Category("Civil Protection")] + public void CivilProtectionAostaAndFriuliPlateShouldBeValidated() + { + // Protezione Civile Aosta -> PC A12 + // Protezione Civile Friuli -> PC A12 + + var ambiguousCarPlates = new[] + { + "PC012", + "PC A23", + "pc z 4 5", + "pc s l9", + }; + + foreach (var plate in ambiguousCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.CivilProtectionAosta)); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.CivilProtectionFriuli)); + } + } + + [Test, Category("Civil Protection")] + public void CivilProtectionBolzanoPlateShouldBeValidated() + { + // Dipartimento Protezione Civile Bolzano -> PC ZS ABC + var validCarPlates = new[] + { + "PCZS123", + "PCZS ABC", + "pczs T45", + "pc zs l9a", + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.CivilProtectionBolzano, result.Items.First().Type); + } + } + + [Test, Category("Civil Protection")] + public void CivilProtectionDepartmentPlateShouldBeValidated() + { + // Dipartimento Protezione Civile -> DPC A0123 + var validCarPlates = new[] + { + "DPCA1234", + "DpC A 4567", + "dpcA 9087", + "DPCa0000", + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.CivilProtectionDepartment, result.Items.First().Type); + } + } + + [Test, Category("Armed forces")] + public void CoastGuardPlateShouldBeValidated() + { + // Guardia Costiera - CP 1000 - CP 1999 (Veicoli di rappresentanza) + // Guardia Costiera - CP 2000 - CP 2999 (Auto, bus, mezzi pesanti) + // Guardia Costiera - CP 3000 - CP 3999 (Motocicli) + // Guardia Costiera - CP 4000 - CP 4999 (Auto, bus, mezzi pesanti) + // Guardia Costiera - CP 0000R - CP 0999R (rimorchi) + + { + var validCarPlates = new[] + { + "CP 1000", + "cp 1999", + " c P 12 34" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.CoastGuardDepartment, result.Items.First().Type); + } + } + + { + var validCarPlates = new[] + { + "CP 2000", + "CP 4000" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.CoastGuard, result.Items.First().Type); + } + } + + { + var ambigouosCarPlates = new[] + { + "cp 2999", + " c P 22 34", + "cp 4999" + }; + + foreach (var plate in ambigouosCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.CoastGuard)); + } + } + + var validMotorbikePlates = new[] + { + "CP 3000", + "cp 3120" + }; + + foreach (var plate in validMotorbikePlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.CoastGuardMotorbike, result.Items.First().Type); + } + + { + var ambigouosMotorbikePlates = new[] + { + " c P 32 34", + "cp 3999" + }; + + foreach (var plate in ambigouosMotorbikePlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.CoastGuardMotorbike)); + } + } + + var validTrailerPlates = new[] + { + "CP 0001R", + "cp 0999R", + " c P 0666 r" + }; + + foreach (var plate in validTrailerPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.CoastGuardTrailer, result.Items.First().Type); + } + } + + [Test, Category("Diplomatic and Consular corps")] + public void ConsularCorpsPlateShouldBeValidated() + { + // Consular Corps -> CC 000 AA + // Please note that there is a conflict with normal car plates + + var validCarPlates = new[] + { + "CC 000 AA", // Albania + "CC123 UA", // Argentina + "CC123 VA", // Argentina (staff) + "CC 666XG", // Vatican State City + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ConsularCorps)); + } + } + + [Test, Category("Diplomatic and Consular corps")] + public void DiplomaticCorpsPlateShouldBeValidated() + { + // Diplomatic Corps -> CD 000 AA + // Please note that there is a conflict with normal car plates + + var validCarPlates = new[] + { + "CD 000 AA", // Albania + "CD123 UA", // Argentina + "CD 666XG", // Vatican State City + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.DiplomaticCorps)); + } + } + + [Test, Category("Fire Fighters")] + public void FireFightersPlateShouldBeValidated() + { + // Vigili del Fuoco -> VF 12345 + // Vigili del Fuoco -> VF R 1234 (trailers) + // Vigili del Fuoco -> VF P 12345 (test plate - ambiguity with standard test plates) + + var validPlates = new[] + { + "VF 12345", + "V F 1234 5", + "vf 12 345" + }; + + foreach (var plate in validPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.FireFighters)); + } + + var validTrailersPlates = new[] + { + "VF r1235", + "V F R 1234", + "vf r12 34" + }; + + foreach (var plate in validTrailersPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.FireFightersTrailer, result.Items.First().Type); + } + + var validTestPlates = new[] + { + "VF p12345", + "V F P 12345", + "vf p12 345" + }; + + foreach (var plate in validTestPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.FireFightersTestVehicle)); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.TestVehicle)); + } + } + + [Test, Category("Fire Fighters")] + public void FireFightersBolzanoPlateShouldBeValidated() + { + // Vigili del Fuoco della Provincia Autonomia di Bolzano -> VFFW AAA + + var validCarPlates = new[] + { + "VFFW123", + "VffW 1A3", + "VF FW AB7", + "vffw999", + "vFFw00d" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.FireFightersBolzano, result.Items.First().Type); + } + } + + [Test, Category("Fire Fighters")] + public void FireFightersTrentoPlateShouldBeValidated() + { + // Vigili del Fuoco della Provincia Autonomia di Trento -> VF000TN + + var validCarPlates = new[] + { + "VF1B3TN", + "vFA01TN", + "vFT42tN", + "vf07Ctn" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.FireFightersTrento, result.Items.First().Type); + } + + var ambiguousCarPlates = new[] + { + "VF123TN", + "vF001TN", + "vF342tN", + "vf070tn" + }; + + foreach (var plate in ambiguousCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.Car)); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.FireFightersTrento)); + } + } + + [Test, Category("Fire Fighters")] + public void FinanceGuardPlateShouldBeValidated() + { + // Guardia di Finanza -> GdiF 000 AA (cars) + // Guardia di Finanza -> GdiF 10000 - GdiF 12000 (motorbikes) + // Guardia di Finanza -> G.diF. 10000 - G.diF. 12000 (motorbikes - pre-1981 numbering) + // Guardia di Finanza -> GdiF 000 R (trailers) + // Guardia di Finanza -> G.diF. 000 R (trailers - pre-1981 numbering) + + var validCarPlates = new[] + { + "GdiF 123AA", + "g di f 453BC", + "GDIF675rd" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.FinanceGuard, result.Items.First().Type); + } + + var validBikesPlates = new[] + { + "GdiF 11345", + "g dif11999", + "G DI F 11111", + "G.diF. 11345", + "g.dif.11999", + "G.DIF.11111" + }; + + foreach (var plate in validBikesPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.FinanceGuardMotorbike, result.Items.First().Type); + } + + var notValidBikesPlates = new[] + { + "GdiF 12345", + "gdif 12000", + "G DI F 09999", + "G.diF.12345", + "g.dif.12000", + "G.DIF.09999" + }; + + foreach (var plate in notValidBikesPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsFalse(result.Items.Any(p => p.Type == PlateType.FinanceGuardMotorbike)); + } + + var validTrailersPlates = new[] + { + "GdiF000R", + "gdif345r", + "GDIF 999r", + "G. diF. 000R", + "g. dif. 345r", + "G.DIF.999r", + }; + + foreach (var plate in validTrailersPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.FinanceGuardTrailer, result.Items.First().Type); + } + } + + [Test, Category("Special vehicles")] + public void ForeignExcursionistsPlateShouldBeValidated() + { + // Escursionisti Esteri -> EE000AA + + var validCarPlates = new[] + { + "EE 123 BB", + "eE 999EE", + "ee010 DB", + "Ee333BA" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.ForeignExcursionists, result.Items.First().Type); + } + } + + [Test, Category("Forestry Corps")] + public void ForestyCorpsPlateShouldBeValidated() + { + // Corpo Forestale dello Stato (<01/01/2017) -> CFS000AA + + var validCarPlates = new[] + { + "CFS 123BB", + "CfS 999 EE", + "cf s 010 DB", + "cfS333BA" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.ForestryCorps, result.Items.First().Type); + } + } + + [Test, Category("Forestry Corps")] + public void ForestyCorpsPalermoPlateShouldBeValidated() + { + // Corpo Forestale della Provincia di Palermo -> CF000PA + + var validCarPlates = new[] + { + "CF 1B3PA", + "cFA01 pA", + "cF T42 Pa", + "cf07Cpa" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.ForestryCorpsPalermo, result.Items.First().Type); + } + + var ambiguousCarPlates = new[] + { + "CF 123PA", + "cF001 pA", + "cF342Pa", + "cf070pa" + }; + + foreach (var plate in ambiguousCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.Car)); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsPalermo)); + } + + var extremelyAmbiguousCarPlates = new[] + { + "Cf FDA pa" + }; + + foreach (var plate in extremelyAmbiguousCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsBolzano)); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsPalermo)); + } + } + + [Test, Category("Forestry Corps")] + public void ForestyCorpsAgrigentoPlateShouldBeValidated() + { + // Corpo Forestale della Provincia di Agrigento -> CF000AG + + var validCarPlates = new[] + { + "CF 1B3AG", + "cFA01 aG", + "cF T42 Ag", + "cf07Cag" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.ForestryCorpsAgrigento, result.Items.First().Type); + } + + var ambiguousCarPlates = new[] + { + "CF123AG", + "cF001aG", + "cF342Ag", + "cf070ag" + }; + + foreach (var plate in ambiguousCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.Car)); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsAgrigento)); + } + + var extremelyAmbiguousCarPlates = new[] + { + "CfFDAag" + }; + + foreach (var plate in extremelyAmbiguousCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsBolzano)); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsAgrigento)); + } + } + + [Test, Category("Forestry Corps")] + public void ForestyCorpsBolzanoPlateShouldBeValidated() + { + // Corpo Forestale della Provincia Autonomia di Bolzano -> CFFD000AA + + var validCarPlates = new[] + { + "CFF D123", + "CFFD 1A3", + "CF FD ABC", + "Cffd999", + "cfFd00d" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.ForestryCorpsBolzano, result.Items.First().Type); + } + } + + [Test, Category("Forestry Corps")] + public void ForestyCorpsAostaPlateShouldBeValidated() + { + // Corpo Forestale della Provincia di Aosta -> CF000AO + + var validCarPlates = new[] + { + "CF 123AO", + "cf342ao", + "CFA01AO", + "cF000aO", + "CfABCAO" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.ForestryCorpsAosta, result.Items.First().Type); + } + } + + [Test, Category("Forestry Corps")] + public void ForestyCorpsCagliariPlateShouldBeValidated() + { + // Corpo Forestale della Provincia di Cagliari -> CFVA000CA + + var validCarPlates = new[] + { + "CFVA678CA", + "CFVA1B3 CA", + "cFva A01 cA", + "cFVAT42ca", + "cfVa07CCA" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.ForestryCorpsCagliari, result.Items.First().Type); + } + } + + [Test, Category("Forestry Corps")] + public void ForestyCorpsCaltanissettaPlateShouldBeValidated() + { + // Corpo Forestale della Provincia di Caltanissetta -> CF000CL + + var validCarPlates = new[] + { + "CF1B3CL", + "cF A 01 cL", + "cFT42Cl", + "cf07Ccl" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.ForestryCorpsCaltanissetta, result.Items.First().Type); + } + + var ambiguousCarPlates = new[] + { + "CF123CL", + "cF001cL", + "cF342Cl", + "cf070cl" + }; + + foreach (var plate in ambiguousCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.Car)); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsCaltanissetta)); + } + + var extremelyAmbiguousCarPlates = new[] + { + "CfFDAcl" + }; + + foreach (var plate in extremelyAmbiguousCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsBolzano)); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsCaltanissetta)); + } + } + + [Test, Category("Forestry Corps")] + public void ForestyCorpsCataniaPlateShouldBeValidated() + { + // Corpo Forestale della Provincia di Catania -> CF000CT + + var validCarPlates = new[] + { + "CF 1B3CT", + "cFA01 cT", + "cFT42Ct", + "cf07Cct" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.ForestryCorpsCatania, result.Items.First().Type); + } + + var ambiguousCarPlates = new[] + { + "CF 123 CT", + "cF001cT", + "cF342Ct", + "cf070ct" + }; + + foreach (var plate in ambiguousCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.Car)); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsCatania)); + } + + var extremelyAmbiguousCarPlates = new[] + { + "CfFDAct" + }; + + foreach (var plate in extremelyAmbiguousCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsBolzano)); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsCatania)); + } + } + + [Test, Category("Forestry Corps")] + public void ForestyCorpsEnnaPlateShouldBeValidated() + { + // Corpo Forestale della Provincia di Enna -> CF000EN + + var validCarPlates = new[] + { + "CF1B3EN", + "cFA01eN", + "cFT42En", + "cf07Cen" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.ForestryCorpsEnna, result.Items.First().Type); + } + + var ambiguousCarPlates = new[] + { + "CF123EN", + "cF001eN", + "cF342En", + "cf070en" + }; + + foreach (var plate in ambiguousCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.Car)); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsEnna)); + } + + var extremelyAmbiguousCarPlates = new[] + { + "CfFDAen" + }; + + foreach (var plate in extremelyAmbiguousCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsBolzano)); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsEnna)); + } + } + + [Test, Category("Forestry Corps")] + public void ForestyCorpsMedioCampidanoPlateShouldBeValidated() + { + // Corpo Forestale della Provincia di Medio Campidano -> CFVA000CA + + var validCarPlates = new[] + { + "CFVA678VS", + "CFVA1B3vs", + "cFvaA01VS", + "cFVAT42vS", + "cfVa07CVs" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.ForestryCorpsMedioCampidano, result.Items.First().Type); + } + } + + [Test, Category("Forestry Corps")] + public void ForestyCorpsMessinaPlateShouldBeValidated() + { + // Corpo Forestale della Provincia di Enna -> CF000EN + + var validCarPlates = new[] + { + "CF1B3ME", + "cFA01mE", + "cFT42Me", + "cf07Cme" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.ForestryCorpsMessina, result.Items.First().Type); + } + + var ambiguousCarPlates = new[] + { + "CF123ME", + "cF001mE", + "cF342Me", + "cf070me" + }; + + foreach (var plate in ambiguousCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.Car)); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsMessina)); + } + + var extremelyAmbiguousCarPlates = new[] + { + "CfFDAme" + }; + + foreach (var plate in extremelyAmbiguousCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsBolzano)); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsMessina)); + } + } + + [Test, Category("Forestry Corps")] + public void ForestyCorpsNuoroPlateShouldBeValidated() + { + // Corpo Forestale della Provincia di Nuoro -> CFVA000NU + + var validCarPlates = new[] + { + "CFVA678NU", + "CFVA1B3nu", + "cFvaA01Nu", + "cFVAT42nU", + "cfVa07CNU" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.ForestryCorpsNuoro, result.Items.First().Type); + } + } + + [Test, Category("Forestry Corps")] + public void ForestyCorpsOgliastraPlateShouldBeValidated() + { + // Corpo Forestale della Provincia dell'Ogliastra -> CFVA000OG + + var validCarPlates = new[] + { + "CFVA678OG", + "CFVA1B3og", + "cFvaA01Og", + "cFVAT42oG", + "cfVa07COG" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.ForestryCorpsOgliastra, result.Items.First().Type); + } + } + + [Test, Category("Forestry Corps")] + public void ForestyCorpsOlbiaTempioPlateShouldBeValidated() + { + // Corpo Forestale della Provincia dell'Ogliastra -> CFVA000OT + + var validCarPlates = new[] + { + "CFVA678OT", + "CFVA1B3ot", + "cFvaA01Ot", + "cFVAT42oT", + "cfVa07COT" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.ForestryCorpsOlbiaTempio, result.Items.First().Type); + } + } + + [Test, Category("Forestry Corps")] + public void ForestyCorpsOristanoPlateShouldBeValidated() + { + // Corpo Forestale della Provincia di S -> CFVA000OR + + var validCarPlates = new[] + { + "CFVA678OR", + "CFVA1B3or", + "cFvaA01Or", + "cFVAT42oR", + "cfVa07COR" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.ForestryCorpsOristano, result.Items.First().Type); + } + } + + [Test, Category("Forestry Corps")] + public void ForestyCorpsRagusaPlateShouldBeValidated() + { + // Corpo Forestale della Provincia di Ragusa -> CF000RG + + var validCarPlates = new[] + { + "CF1B3RG", + "cFA01rG", + "cFT42Rg", + "cf07Crg" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.ForestryCorpsRagusa, result.Items.First().Type); + } + + var ambiguousCarPlates = new[] + { + "CF123RG", + "cF001rG", + "cF342Rg", + "cf070rg" + }; + + foreach (var plate in ambiguousCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.Car)); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsRagusa)); + } + + var extremelyAmbiguousCarPlates = new[] + { + "CfFDArg" + }; + + foreach (var plate in extremelyAmbiguousCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsBolzano)); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsRagusa)); + } + } + + [Test, Category("Forestry Corps")] + public void ForestyCorpsSassariPlateShouldBeValidated() + { + // Corpo Forestale della Provincia di Sassari -> CFVA000SS + + var validCarPlates = new[] + { + "CFVA678SS", + "CFVA1B3ss", + "cFvaA01Ss", + "cFVAT42sS", + "cfVa07CSS" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.ForestryCorpsSassari, result.Items.First().Type); + } + } + + [Test, Category("Forestry Corps")] + public void ForestyCorpsSiracusaPlateShouldBeValidated() + { + // Corpo Forestale della Provincia di Siracusa -> CF000SR + + var validCarPlates = new[] + { + "CF1B3SR", + "cFA01sR", + "cFT42Sr", + "cf07Csr" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.ForestryCorpsSiracusa, result.Items.First().Type); + } + + var ambiguousCarPlates = new[] + { + "CF123SR", + "cF001sR", + "cF342Sr", + "cf070sr" + }; + + foreach (var plate in ambiguousCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.Car)); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsSiracusa)); + } + + var extremelyAmbiguousCarPlates = new[] + { + "CfFDAsr" + }; + + foreach (var plate in extremelyAmbiguousCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsBolzano)); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsSiracusa)); + } + } + + [Test, Category("Forestry Corps")] + public void ForestyCorpsSudSardegnaPlateShouldBeValidated() + { + // Corpo Forestale della Provincia di Oristano -> CFVA000SU + + var validCarPlates = new[] + { + "CFVA678SU", + "CFVA1B3su", + "cFvaA01Su", + "cFVAT42sU", + "cfVa07CSU" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.ForestryCorpsSudSardegna, result.Items.First().Type); + } + } + + [Test, Category("Forestry Corps")] + public void ForestyCorpsTrapaniPlateShouldBeValidated() + { + // Corpo Forestale della Provincia di Trapani -> CF000TP + + var validCarPlates = new[] + { + "CF1B3TP", + "cFA01tP", + "cFT42Tp", + "cf07Ctp" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.ForestryCorpsTrapani, result.Items.First().Type); + } + + var ambiguousCarPlates = new[] + { + "CF123Tp", + "cF001tP", + "cF342Tp", + "cf070tp" + }; + + foreach (var plate in ambiguousCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.Car)); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsTrapani)); + } + + var extremelyAmbiguousCarPlates = new[] + { + "CfFDAtp" + }; + + foreach (var plate in extremelyAmbiguousCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsBolzano)); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsTrapani)); + } + } + + [Test, Category("Forestry Corps")] + public void ForestyCorpsTrentoPlateShouldBeValidated() + { + // Corpo Forestale della Provincia Autonomia di Trenot -> CF000TN + + var validCarPlates = new[] + { + "CF1B3TN", + "cFA01TN", + "cFT42tN", + "cf07Ctn" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.ForestryCorpsTrento, result.Items.First().Type); + } + + var ambiguousCarPlates = new[] + { + "CF123TN", + "cF001TN", + "cF342tN", + "cf070tn" + }; + + foreach (var plate in ambiguousCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.Car)); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsTrento)); + } + + var extremelyAmbiguousCarPlates = new[] + { + "CfFDAtn" + }; + + foreach (var plate in extremelyAmbiguousCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsBolzano)); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ForestryCorpsTrento)); + } + } + + [Test, Category("Armed Forces")] + public void ItalianAirForcePlateShouldBeValidated() + { + // Italian Air Force plates -> AM AA 000 (starting from AM AH 500) + + var validCarPlates = new[] + { + "AM AH 500", + "AM AH 501", + "AM AH 700", + "am bg 666", + "amll123", + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ItalianAirForce)); + } + + var notValidCarPlates = new[] + { + "AM AH 499", + "am aa 666", + "amab123", + }; + + foreach (var plate in notValidCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsFalse(result.IsFound); + Assert.IsFalse(result.Items.Any(p => p.Type == PlateType.ItalianAirForce)); + } + } + + [Test, Category("Armed Forces")] + public void ItalianAirForceMotorbikePlateShouldBeValidated() + { + // Italian Air Force motorbikes plates -> AM A/0000 (starting from AM A/6000) + + var validPlates = new[] + { + "AM A/6000", + "AM A/6001", + "am b/1234", + "ama/7700", + }; + + foreach (var plate in validPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ItalianAirForceMotorbike)); + } + + var notValidPlates = new[] + { + "AM A/5000", + "am A/0000" + }; + + foreach (var plate in notValidPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsFalse(result.IsFound); + Assert.IsFalse(result.Items.Any(p => p.Type == PlateType.ItalianAirForceMotorbike)); + } + } + + [Test, Category("Armed Forces")] + public void ItalianArmyPlateShouldBeValidated() + { + // Italian Army plates -> EI AA 000 + + var validCarPlates = new[] + { + "EI AH 500", + "EI AH 501", + "ei AH 700", + "ei bg 666", + "eiea637", + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ItalianArmy)); + } + + var notValidCarPlates = new[] + { + "EI VS 500", + "EI VS 501", + "ei vs 700", + "ei Vs 666", + "eivs637", + }; + + foreach (var plate in notValidCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.IsFalse(result.Items.Any(p => p.Type == PlateType.ItalianArmy)); + } + } + + [Test, Category("Armed Forces")] + public void ItalianArmyHistoricalVehiclePlateShouldBeValidated() + { + // Italian Army historical vehicles plates -> EI VS 000 + + var validCarPlates = new[] + { + "EI VS 500", + "EI VS 501", + "ei vs 700", + "ei Vs 666", + "eivs637", + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ItalianArmyHistoricalVehicle)); + } + } + + [Test, Category("Armed Forces")] + public void ItalianArmyMotorbikePlateShouldBeValidated() + { + // Italian Army motorbikes plates -> EI A 0000 + + var validPlates = new[] + { + "EI A 0000", + "EI B 0501", + "ei c 7000", + "ei d 6966", + "eih9637", + }; + + foreach (var plate in validPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ItalianArmyMotorbike)); + } + } + + [Test, Category("Armed Forces")] + public void ItalianArmyTankPlateShouldBeValidated() + { + // Italian Army tanks and armored vehicles plates -> EI 000000 (range EI 900000 - EI 999999 is reserved for old trailers) + + var validPlates = new[] + { + "EI 000000", + "EI 000 001", + "ei 123456", + "ei 7 6 5 4 5 6" + }; + + foreach (var plate in validPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ItalianArmyTank)); + } + + var notValidPlates = new[] + { + "EI 900000", + "EI 999999", + "ei 950000" + }; + + foreach (var plate in notValidPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsFalse(result.IsFound); + Assert.IsFalse(result.Items.Any(p => p.Type == PlateType.ItalianArmyTank)); + } + } + + [Test, Category("Armed Forces")] + public void ItalianArmyTrailerPlateShouldBeValidated() + { + // Italian Army Trailers plates -> RIMORCHIO EI AA 000 + + var validPlates = new[] + { + "RIMORCHIO EI AH 50", + "rimorchio EI AH 51", + "ri mo rc hio ei AH 70", + "RiMorChio ei bg 66", + "rimorchioeiea37", + }; + + foreach (var plate in validPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ItalianArmyTrailer)); + } + } + + [Test, Category("Armed Forces")] + public void ItalianNavyPlateShouldBeValidated() + { + // Italian Navy plates -> MM AA 000 + + var validCarPlates = new[] + { + "MM AH 500", + "MM AH 501", + "MM AH 700", + "mm bg 666", + "mmea637", + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ItalianNavy)); + } + } + + [Test, Category("Armed Forces")] + public void ItalianNavyTrailerPlateShouldBeValidated() + { + // Italian Navy Trailers plates -> RIMORCHIO MM AA 000 + + var validPlates = new[] + { + "RIMORCHIO MM AH 530", + "rimorchio MM AH 151", + "ri mo rc hio mm AH 070", + "RiMorChio mm bg 166", + "rimorchiommea367", + }; + + foreach (var plate in validPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.ItalianNavyTrailer)); + } + } + + [Test, Category("Italian Red Cross")] + public void ItalianRedCrossPlateShouldBeValidated() + { + // Croce Rossa Italiana -> CRI000AA (>2007), CRI00000 (2002-2007), CRI00000 (1983-2002) + var validCarPlates = new[] + { + "CRI001AA", + "CRI12345", + "CRIA118C", + "CriB138d" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.ItalianRedCross, result.Items.First().Type); + } + } + + [Test, Category("Italian Red Cross")] + public void ItalianRedCrossMotorbikePlateShouldBeValidated() + { + // Croce Rossa Italiana (Motocicli, rimorchi, roulotte e ciclomotori). -> CRI000, CRI0000 + + var validCarPlates = new[] + { + "CRI001", + "Cri123", + "cri111", + "Cri1234", + "CRI1034" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.ItalianRedCrossMotorbike, result.Items.First().Type); + } + } + + [Test, Category("Police forces")] + public void LocalPolicePlateShouldBeValidated() + { + // Polizia locale e municipale -> POLIZIA LOCALE YA 000 AA + + var validCarPlates = new[] + { + "POLIZIA LOCALE YA 000 AA", + "POLIZIAlocale yg 987 kk" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.LocalPolice, result.Items.First().Type); + } + } + + [Test, Category("Police forces")] + public void LocalPoliceMotorcyclePlateShouldBeValidated() + { + // Polizia locale e municipale -> POLIZIA LOCALE Y 00000 + // (Ciclomotori motocarri e mototrattori di cilindrata inferiore a 50 cm³, e quadricicli leggeri) + + var validCarPlates = new[] + { + "POLIZIA LOCALE YA 00000", + "POLIZIAlocale yh 987 65" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.LocalPoliceMotorcycle, result.Items.First().Type); + } + } + + [Test, Category("Police forces")] + public void LocalPoliceMotorbikePlateShouldBeValidated() + { + // Polizia locale e municipale -> POLIZIA LOCALE Y 000 AA + // Motocicli, motoveicoli, motocarri, mototrattori e quadricicli di cilindrata superiore a 50 cm³ + var validCarPlates = new[] + { + "POLIZIA LOCALE Y 000 AA", + "POLIZIAlocale y 023be" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.LocalPoliceMotorbike, result.Items.First().Type); + } + } + + [Test, Category("Police forces")] + public void PenitentiaryPolicePlateShouldBeValidated() + { + // Polizia penitenziaria -> POLIZIA PENITENZIARIA 000 AA + var validCarPlates = new[] + { + "POLIZIA PENITENZIARIA 000 AA", + "POLIZIAPENITENZIARIA 023be" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.PenitentiaryPolice, result.Items.First().Type); + } + } + + [Test, Category("Diplomatic and Consular corps")] + public void SovereignMilitaryOrderOfMaltaPlateShouldBeValidated() + { + // Sovrano Militare Ordine di Malta-> SMOM 000 (cars) + // Sovrano Militare Ordine di Malta-> SMOM M 000 (motorbikes) + + var validCarPlates = new[] + { + "SMOM123", + "smom453", + "sMoM675" + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.SovereignMilitaryOrderOfMalta, result.Items.First().Type); + } + + var validBikesPlates = new[] + { + "SMOMm123", + "smomM453", + "sMoMM675" + }; + + foreach (var plate in validBikesPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.SovereignMilitaryOrderOfMaltaMotorbike, result.Items.First().Type); + } + } + + [Test, Category("Police forces")] + public void StatePolicePlateShouldBeValidated() + { + // Polizia di Stato -> POLIZIA A 0000 + var validCarPlates = new[] + { + "POLIZIA A 0000", + "POLIZIA k 6677", + "POL IZIA k6677", + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.StatePolice, result.Items.First().Type); + } + } + + [Test, Category("Special vehicles")] + public void TestPlateShouldBeValidated() + { + // Test plates -> X0 P AAAAA + + var validCarPlates = new[] + { + "X0 P 1234A", + "Mi P TO0O0", + "RAP1n4t0", + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.TestVehicle)); + } + } + + [Test, Category("Diplomatic and Consular corps")] + public void UnitedNationsPlateShouldBeValidated() + { + // ONU service vehicles -> UN 000 AA + // ONU staff private vehicles -> UNP 000 AA (ambiguity with standard test plates) + // ONU in transit vehicles -> UNT 000 AA + + { + var validCarPlates = new[] + { + "UN 000 AA", + "un123zz", + "u n 666 o o", + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.UnitedNations, result.Items.First().Type); + } + } + + { + var validCarPlates = new[] + { + "UNP 000 AA", + "unp123zz", + "u n p 666 o o", + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.UnitedNationsStaff)); + Assert.IsTrue(result.Items.Any(p => p.Type == PlateType.TestVehicle)); + } + } + + { + var validCarPlates = new[] + { + "UNT 000 AA", + "unt123zz", + "u n t666 o o", + }; + + foreach (var plate in validCarPlates) + { + var result = _platesHelper.TryIdentifyPlate(plate); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(1, result.Items.Count); + Assert.AreEqual(PlateType.UnitedNationsInTransit, result.Items.First().Type); + } + } + } + + [Test, Category("Special vehicles")] + public void WellKnownPlateShouldBeValidated() + { + // POLIZIAE8300 -> Lamborghini Gallardo Polizia di Stato + var result = _platesHelper.TryIdentifyPlate("POLIZIA E8300"); + + Assert.IsNotNull(result); + Assert.IsTrue(result.IsFound); + Assert.AreEqual(2, result.Items.Count); + Assert.IsTrue(result.Items.Any(i => i is WellKnownPlate && i.Type == PlateType.StatePolice)); + } + + [Test, Category("Common vehicles")] + public void PlatesHelperShouldThrow() + { + Assert.Throws(() => + { + var result = _platesHelper.TryIdentifyPlate(string.Empty); + }); + + Assert.Throws(() => + { + var result = _platesHelper.TryIdentifyPlate(" "); + }); + } + + /* + + [Test] + public void FiscalCodeShouldBeCalculated() + { + // NOTE: The names and all the data used in this tests are fictitious. + // No identification with actual persons (living or deceased), + // places, buildings, and products is intended or should be inferred. + + { + var assert = "MRNLSS90H27A271J"; + var result = FiscalCodeHelper.CalculateFiscalCode("Marinelli", "Alessio", new DateTime(1990, 6, 27), "M", "A271"); + + TestContext.WriteLine($"TEST: {assert} - {result}"); + + Assert.AreEqual(assert, result); + } + + { + var assert = "VRDGNN80A10E783B"; + var result = FiscalCodeHelper.CalculateFiscalCode("Verdi", "Giovanni", new DateTime(1980, 1, 10), "M", "E783"); + + TestContext.WriteLine($"TEST: {assert} - {result}"); + + Assert.AreEqual(assert, result); + } + + { + var assert = "RSSMRA69H45Z602F"; + var result = FiscalCodeHelper.CalculateFiscalCode("Rossi", "Maria", new DateTime(1969, 6, 5), "F", "z602"); + + TestContext.WriteLine($"TEST: {assert} - {result}"); + + Assert.AreEqual(assert, result); + } + + { + var assert = "BLUHUX64T01Z210I"; + var result = FiscalCodeHelper.CalculateFiscalCode("BLU", "HU", new DateTime(1964, 12, 1), "M", "z210"); + + TestContext.WriteLine($"TEST: {assert} - {result}"); + + Assert.AreEqual(assert, result); + } + + { + var assert = "MAXJIX17L51Z213S"; + var result = FiscalCodeHelper.CalculateFiscalCode("MA", "JI", new DateTime(2017, 7, 11), "f", "Z213"); + + TestContext.WriteLine($"TEST: {assert} - {result}"); + + Assert.AreEqual(assert, result); + } + + { + var assert = "XGNIUX23A07Z110V"; + var result = FiscalCodeHelper.CalculateFiscalCode("XI GONG", "IU", new DateTime(2023, 1, 7), "m", "Z110"); + + TestContext.WriteLine($"TEST: {assert} - {result}"); + + Assert.AreEqual(assert, result); + } + + { + var assert = "NRETMS80A01A271D"; + var result = FiscalCodeHelper.CalculateFiscalCode("neri", "tommaso", new DateTime(1980, 1, 1), "m", "a271"); + + TestContext.WriteLine($"TEST: {assert} - {result}"); + + Assert.AreEqual(assert, result); + } + } + + [Test] + public void FiscalCodeCalculationShouldThrow() + { + Assert.Throws(() => + { + var result = FiscalCodeHelper.CalculateFiscalCode(string.Empty, "Alessio", new DateTime(1990, 6, 27), "M", "A271"); + }); + + Assert.Throws(() => + { + var result = FiscalCodeHelper.CalculateFiscalCode(" ", "Alessio", new DateTime(1990, 6, 27), "M", "A271"); + }); + + Assert.Throws(() => + { + + var result = FiscalCodeHelper.CalculateFiscalCode("Marinelli", " ", new DateTime(1990, 6, 27), "M", "A271"); + }); + + Assert.Throws(() => + { + var result = FiscalCodeHelper.CalculateFiscalCode("Marinelli", "Alessio", new DateTime(1990, 6, 27), "", "A271"); + }); + + Assert.Throws(() => + { + var result = FiscalCodeHelper.CalculateFiscalCode("Marinelli", "Alessio", new DateTime(1990, 6, 27), "AnyOtherValue", "A271"); + }); + + Assert.Throws(() => + { + var result = FiscalCodeHelper.CalculateFiscalCode("Marinelli", "Alessio", new DateTime(1990, 6, 27), "M", string.Empty); + }); + + Assert.Throws(() => + { + var result = FiscalCodeHelper.CalculateFiscalCode("Marinelli", "Alessio", new DateTime(1990, 6, 27), "M", "WrongBelfioreFormat"); + }); + } + + [Test] + public void HomocodiesShouldBeCalculated() + { + { + var result = FiscalCodeHelper.GenerateHomocodies("MRNLSS90H27A271J"); + + Assert.IsNotNull(result); + + var expected = new List() { + "MRNLSS90H27A27MB", + "MRNLSS90H27A2TMN", + "MRNLSS90H27ANTMC", + "MRNLSS90H2TANTMZ", + "MRNLSS90HNTANTMK", + "MRNLSS9LHNTANTMV", + "MRNLSSVLHNTANTMK", + "MRNLSS90H27A27MB", + "MRNLSS90H27A2T1V", + "MRNLSS90H27AN71Y", + "MRNLSS90H2TA271G", + "MRNLSS90HN7A271U", + "MRNLSS9LH27A271U", + "MRNLSSV0H27A271Y" + }; + + Assert.AreEqual(expected.Count, result.Count); + + expected.ForEach(x => { Assert.IsTrue(result.Contains(x)); }); + } + } + + [Test] + public void HomocodiesCalculationShouldThrow() + { + Assert.Throws(() => + { + var result = FiscalCodeHelper.GenerateHomocodies(string.Empty); + }); + } + + [Test] + public void HomocodiesShouldFailCalculation() + { + { + var result = FiscalCodeHelper.GenerateHomocodies("WrongString"); + + Assert.IsNotNull(result); + Assert.AreEqual(0, result.Count); + } + + { + var result = FiscalCodeHelper.GenerateHomocodies("12345678901"); // temporary fiscal code + + Assert.IsNotNull(result); + Assert.AreEqual(0, result.Count); + } + } + + [Test] + public void HomocodyShouldBeValidated() + { + { + var expected = new List() { + "MRNLSS90H27A27MB", + "MRNLSS90H27A2TMN", + "MRNLSS90H27ANTMC", + "MRNLSS90H2TANTMZ", + "MRNLSS90HNTANTMK", + "MRNLSS9LHNTANTMV", + "MRNLSSVLHNTANTMK", + "MRNLSS90H27A27MB", + "MRNLSS90H27A2T1V", + "MRNLSS90H27AN71Y", + "MRNLSS90H2TA271G", + "MRNLSS90HN7A271U", + "MRNLSS9LH27A271U", + "MRNLSSV0H27A271Y" + }; + + expected.ForEach(x => Assert.IsTrue(FiscalCodeHelper.IsHomocody("MRNLSS90H27A271J", x))); + } + } + + [Test] + public void HomocodyShouldFailValidation() + { + { + var expected = new List() { + "WrongString", + "12345678901" + }; + + expected.ForEach(x => Assert.IsFalse(FiscalCodeHelper.IsHomocody("MRNLSS90H27A271J", x))); + } + }*/ + } +} \ No newline at end of file diff --git a/src/ItalianToolkit/ItalianToolkit.csproj b/src/ItalianToolkit/ItalianToolkit.csproj index 056f861..a06b125 100644 --- a/src/ItalianToolkit/ItalianToolkit.csproj +++ b/src/ItalianToolkit/ItalianToolkit.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 diff --git a/src/ItalianToolkit/People/FiscalCodeHelper.cs b/src/ItalianToolkit/People/FiscalCodeHelper.cs index 2234a16..2c2a7b7 100644 --- a/src/ItalianToolkit/People/FiscalCodeHelper.cs +++ b/src/ItalianToolkit/People/FiscalCodeHelper.cs @@ -405,7 +405,7 @@ private static string ParseFirstName(string firstName) result.Append(firstName[i]); Cont += 1; if (Cont == 4) - return result.ToString(); ; + return result.ToString(); } } diff --git a/src/ItalianToolkit/Transports/Models/DiplomaticPlate.cs b/src/ItalianToolkit/Transports/Models/DiplomaticPlate.cs new file mode 100644 index 0000000..0219e3b --- /dev/null +++ b/src/ItalianToolkit/Transports/Models/DiplomaticPlate.cs @@ -0,0 +1,7 @@ +namespace ItalianToolkit.Transports.Models +{ + public class DiplomaticPlate : Plate + { + public string DiplomaticDetails { get; set; } + } +} diff --git a/src/ItalianToolkit/Transports/Models/Plate.cs b/src/ItalianToolkit/Transports/Models/Plate.cs new file mode 100644 index 0000000..96c1634 --- /dev/null +++ b/src/ItalianToolkit/Transports/Models/Plate.cs @@ -0,0 +1,11 @@ +namespace ItalianToolkit.Transports.Models +{ + public class Plate + { + public string PlateNumber { get; set; } + + public PlateType Type { get; set; } = PlateType.Unknown; + + public bool IsPlateRecognized => Type != PlateType.Unknown; + } +} diff --git a/src/ItalianToolkit/Transports/Models/PlateSearchResult.cs b/src/ItalianToolkit/Transports/Models/PlateSearchResult.cs new file mode 100644 index 0000000..313a801 --- /dev/null +++ b/src/ItalianToolkit/Transports/Models/PlateSearchResult.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using System.Linq; + +namespace ItalianToolkit.Transports.Models +{ + public class PlateSearchResult + { + public bool IsFound => Items.Any(p => p.Type != PlateType.Unknown); + + public List Items { get; set; } = new List { }; + } +} diff --git a/src/ItalianToolkit/Transports/Models/PlateType.cs b/src/ItalianToolkit/Transports/Models/PlateType.cs new file mode 100644 index 0000000..2eb0e66 --- /dev/null +++ b/src/ItalianToolkit/Transports/Models/PlateType.cs @@ -0,0 +1,77 @@ +namespace ItalianToolkit.Transports.Models +{ + public enum PlateType + { + Unknown = 0, + Car, + Motorcycle, + Motorbike, + Trailer, + + Carabineers, + CivilProtectionAosta, + CivilProtectionBolzano, + CivilProtectionDepartment, + CivilProtectionFriuli, + CoastGuard, + CoastGuardDepartment, + CoastGuardMotorbike, + CoastGuardTrailer, + ConsularCorps, + DiplomaticCorps, + FinanceGuard, + FinanceGuardMotorbike, + FinanceGuardTrailer, + FireFighters, + FireFightersBolzano, + FireFightersTrailer, + FireFightersTestVehicle, + FireFightersTrento, + ForeignExcursionists, + ForestryCorps, + ForestryCorpsAgrigento, + ForestryCorpsAosta, + ForestryCorpsBolzano, + ForestryCorpsCagliari, + ForestryCorpsCaltanissetta, + ForestryCorpsCarboniaIglesias, + ForestryCorpsCatania, + ForestryCorpsEnna, + ForestryCorpsFriuli, + ForestryCorpsMedioCampidano, + ForestryCorpsMessina, + ForestryCorpsNuoro, + ForestryCorpsOgliastra, + ForestryCorpsOlbiaTempio, + ForestryCorpsOristano, + ForestryCorpsPalermo, + ForestryCorpsRagusa, + ForestryCorpsSassari, + ForestryCorpsSiracusa, + ForestryCorpsSudSardegna, + ForestryCorpsTrapani, + ForestryCorpsTrento, + ItalianAirForce, + ItalianAirForceMotorbike, + ItalianArmy, + ItalianArmyHistoricalVehicle, + ItalianArmyMotorbike, + ItalianArmyTank, + ItalianArmyTrailer, + ItalianNavy, + ItalianNavyTrailer, + ItalianRedCross, + ItalianRedCrossMotorbike, + LocalPolice, + LocalPoliceMotorcycle, + LocalPoliceMotorbike, + PenitentiaryPolice, + SovereignMilitaryOrderOfMalta, + SovereignMilitaryOrderOfMaltaMotorbike, + StatePolice, + TestVehicle, + UnitedNations, + UnitedNationsStaff, + UnitedNationsInTransit + } +} diff --git a/src/ItalianToolkit/Transports/Models/WellKnownPlate.cs b/src/ItalianToolkit/Transports/Models/WellKnownPlate.cs new file mode 100644 index 0000000..098145c --- /dev/null +++ b/src/ItalianToolkit/Transports/Models/WellKnownPlate.cs @@ -0,0 +1,7 @@ +namespace ItalianToolkit.Transports.Models +{ + public class WellKnownPlate : Plate + { + public string Details { get; set; } + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifier.cs new file mode 100644 index 0000000..07119e4 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifier.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using ItalianToolkit.Transports.Models; +using ItalianToolkit.Transports.PlatesIdentifierPlugins; + +namespace ItalianToolkit.Transports +{ + public class PlatesIdentifier + { + private List _plugins = new List(); + + public PlatesIdentifier() + { + var plugins = AppDomain.CurrentDomain.GetAssemblies() + .SelectMany(s => s.GetTypes()) + .Where(p => typeof(IPlatesIdentifierPlugin).IsAssignableFrom(p) && p.IsClass && !p.IsAbstract); + + foreach (var plugin in plugins) + { + var pluginInstance = (IPlatesIdentifierPlugin)Activator.CreateInstance(plugin); + + _plugins.Add(pluginInstance); + } + } + + public PlateSearchResult TryIdentifyPlate(string plateNumber) + { + if (string.IsNullOrWhiteSpace(plateNumber)) + { + throw new ArgumentException($"'{nameof(plateNumber)}' cannot be null or whitespace.", nameof(plateNumber)); + } + + PlateSearchResult result = new PlateSearchResult(); + + foreach (var plugin in _plugins) + { + var res = plugin.TryIdentifyPlate(plateNumber); + + if (!(res is null)) + { + result.Items.Add(res); + } + } + + return result; + } + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/CarPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/CarPlateIdentifier.cs new file mode 100644 index 0000000..718371f --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/CarPlateIdentifier.cs @@ -0,0 +1,8 @@ +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class CarPlateIdentifier : RegexPlateIdentifier + { + public override Models.PlateType PlateType => Models.PlateType.Car; + public override string Pattern => @"^(?!EE)(?!Ee)(?!eE)(?!ee)[A-HJ-NPR-TVY-Za-hj-npr-tvy-z][A-HJ-NPR-TV-Za-hj-npr-tv-z]\d{3}[A-HJ-NPR-TV-Za-hj-npr-tv-z]{2}\b$"; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/CarabineersPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/CarabineersPlateIdentifier.cs new file mode 100644 index 0000000..a3639a9 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/CarabineersPlateIdentifier.cs @@ -0,0 +1,9 @@ +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class CarabineersPlateIdentifier : RegexPlateIdentifier + { + public override Models.PlateType PlateType => Models.PlateType.Carabineers; + + public override string Pattern => @"^[cC]{2}[A-Za-z]{2}[0-9]{3}\b$"; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/CivilProtectionAostaValleyPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/CivilProtectionAostaValleyPlateIdentifier.cs new file mode 100644 index 0000000..2e56985 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/CivilProtectionAostaValleyPlateIdentifier.cs @@ -0,0 +1,9 @@ +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class CivilProtectionAostaValleyPlateIdentifier : RegexPlateIdentifier + { + public override Models.PlateType PlateType => Models.PlateType.CivilProtectionAosta; + + public override string Pattern => @"^[pP][cC][A-Za-z0-9]{3}\b$"; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/CivilProtectionBolzanoPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/CivilProtectionBolzanoPlateIdentifier.cs new file mode 100644 index 0000000..53db54c --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/CivilProtectionBolzanoPlateIdentifier.cs @@ -0,0 +1,9 @@ +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class CivilProtectionBolzanoPlateIdentifier : RegexPlateIdentifier + { + public override Models.PlateType PlateType => Models.PlateType.CivilProtectionBolzano; + + public override string Pattern => @"^[pP][cC][zZ][sS][A-Za-z0-9]{3}\b$"; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/CivilProtectionFriuliPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/CivilProtectionFriuliPlateIdentifier.cs new file mode 100644 index 0000000..0a28a99 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/CivilProtectionFriuliPlateIdentifier.cs @@ -0,0 +1,9 @@ +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class CivilProtectionFriuliPlateIdentifier : RegexPlateIdentifier + { + public override Models.PlateType PlateType => Models.PlateType.CivilProtectionFriuli; + + public override string Pattern => @"^[pP][cC][A-Za-z0-9]{3}\b$"; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/CivilProtectionPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/CivilProtectionPlateIdentifier.cs new file mode 100644 index 0000000..1a00b8c --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/CivilProtectionPlateIdentifier.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using ItalianToolkit.Transports.Models; + +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class CivilProtectionPlateIdentifier : RegexMultiPlateIdentifier + { + public override Dictionary Patterns => new Dictionary() + { + { + PlateType.CivilProtectionDepartment, + @"^[dD][pP][cC][A-HJ-NPR-TV-Za-hj-npr-tv-z]\d{4}\b$" + } + }; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/CoastGuardPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/CoastGuardPlateIdentifier.cs new file mode 100644 index 0000000..571a327 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/CoastGuardPlateIdentifier.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using ItalianToolkit.Transports.Models; + +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class CoastGuardPlateIdentifier : RegexMultiPlateIdentifier + { + public override Dictionary Patterns => new Dictionary() + { + { + PlateType.CoastGuardDepartment, + @"^[cC][pP][1][0-9]{3}\b$" + },{ + PlateType.CoastGuard, + @"^[cC][pP][24][0-9]{3}\b$" + },{ + PlateType.CoastGuardMotorbike, + @"^[cC][pP][3][0-9]{3}\b$" + },{ + PlateType.CoastGuardTrailer, + @"^[cC][pP][0][0-9]{3}[rR]\b$" + }, + }; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ConsularCorpsPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ConsularCorpsPlateIdentifier.cs new file mode 100644 index 0000000..6ff41b9 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ConsularCorpsPlateIdentifier.cs @@ -0,0 +1,217 @@ +using System.Collections.Generic; +using System.Text.RegularExpressions; +using ItalianToolkit.Transports.Models; + +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class ConsularCorpsPlateIdentifier : IPlatesIdentifierPlugin + { + public PlateType PlateType => PlateType.ConsularCorps; + + public string Pattern => @"^[cC][cC][0-9]{3}([A-Za-z]{2})\b$"; + + private readonly Dictionary _diplomaticCorpsCodes = new Dictionary() + { + { "AA", "Albania" }, + { "AC", "Austria"}, + { "AE", "Belgium"}, + { "AG", "Bulgaria"}, + { "AK", "Czech Republic"}, + { "AM", "Cyprus"}, + { "AN", "Denmark"}, + { "AP", "Finland"}, + { "AQ", "France"}, + { "AU", "Germany"}, + { "AV", "West Germany (Federal Republic of Germany)"}, + { "BB", "Croatia"}, + { "BC", "Great Britain"}, + { "BF", "Slovenia"}, + { "BG", "Greece"}, + { "BM", "Ireland"}, + { "BN", "Italy (Holy See)"}, + { "BP", "Serbia"}, + { "BQ", "Croatia"}, + { "BR", "Luxembourg"}, + { "BS", "Malta"}, + { "BT", "Monaco"}, + { "BV", "Norway"}, + { "BX", "Netherlands"}, + { "CA", "Poland"}, + { "CC", "Portugal"}, + { "CE", "Romania"}, + { "CG", "San Marino"}, + { "CH", "Spain"}, + { "CQ", "Switzerland"}, + { "CM", "Switzerland"}, + { "CN", "Sweden"}, + { "CR", "Turkey"}, + { "CX", "Hungary"}, + { "DA", "Russian Federation"}, + { "DC", "the Ukraine"}, + { "DD", "Uzbekistan"}, + { "DE", "Vatican City State (Apostolic Nunciature)"}, + { "DF", "Estonia"}, + { "DG", "Macedonia"}, + { "DH", "Bosnia-Herzegovina"}, + { "DL", "Slovakian Republic"}, + { "DM", "Armenia"}, + { "DN", "Georgia"}, + { "DP", "Kazakhstan"}, + { "DQ", "Latvia"}, + { "DR", "Belarus"}, + { "DS", "Lithuania"}, + { "DT", "Moldava"}, + { "DV", "Iceland"}, + { "DZ", "Azerbaijan"}, + { "EA", "Burkina Faso"}, + { "EB", "Dominica"}, + { "EC", "Uganda"}, + { "ED", "Burundi"}, + { "EF", "Rwanda"}, + { "EG", "Zimbawe"}, + { "EH", "Qatar"}, + { "EL", "Chad"}, + { "EM", "Mauritania"}, + { "EN", "Eritrea"}, + { "EP", "Mali"}, + { "ER", "Belize"}, + { "ES", "Equatorial Guinea c/o FAO"}, + { "ET", "Kosovo"}, + { "EU", "Benin"}, + { "GA", "Afghanistan"}, + { "GB", "Saudi Arabia"}, + { "GC", "Bangladesh"}, + { "GD", "Myanmar"}, + { "GE", "Taiwan"}, + { "GF", "China"}, + { "GK", "Philippines"}, + { "GL", "North Korea"}, + { "GM", "Korea"}, + { "GP", "Arab Emirates"}, + { "GQ", "Philippines"}, + { "GS", "Japan"}, + { "GZ", "Jordan"}, + { "HA", "India"}, + { "HC", "Indonesia"}, + { "HE", "Iran"}, + { "HF", "Iraq"}, + { "HL", "Israel"}, + { "HN", "Kuwait"}, + { "HQ", "Kuwait"}, + { "HR", "Lebanon"}, + { "HS", "Malaysia"}, + { "HT", "Oman"}, + { "HV", "Pakistan"}, + { "HX", "Syria"}, + { "LA", "Sri Lanka"}, + { "LB", "Thailand"}, + { "LE", "Vietnam"}, + { "LF", "Yemen"}, + { "LH", "Montenegro"}, + { "LM", "East Timor"}, + { "NA", "Algeria"}, + { "NC", "Angola"}, + { "ND", "Cameroon"}, + { "NF", "Cape Verde"}, + { "NG", "Central African Republic"}, + { "NH", "Republic of Congo"}, + { "NL", "Ivory Coast"}, + { "NM", "Egypt"}, + { "NR", "Ethiopia"}, + { "NT", "Gabon"}, + { "NX", "Ghana"}, + { "PA", "Guinea"}, + { "PB", "Kenya"}, + { "PC", "Lesotho"}, + { "PD", "Liberia"}, + { "PE", "Libya"}, + { "PL", "Madagascar"}, + { "PN", "Morocco"}, + { "PQ", "Nigeria"}, + { "PR", "Tunisia"}, + { "PS", "Senegal"}, + { "PT", "Sierra Leone"}, + { "PV", "Mozambico"}, + { "PX", "Somalia"}, + { "QA", "South Africa"}, + { "QC", "Sudan"}, + { "QE", "Tanzania"}, + { "QG", "Tunisia"}, + { "QL", "Democratic Republic of Congo"}, + { "QN", "Zambia"}, + { "QP", "Niger"}, + { "SA", "Canada"}, + { "SD", "Mexico"}, + { "SF", "United States of America"}, + { "SH", "United States of America"}, + { "SL", "United States of America"}, + { "SN", "United States of America"}, + { "SQ", "United States of America"}, + { "TA", "Costa Rica"}, + { "TC", "Cuba"}, + { "TE", "Dominican Republic"}, + { "TF", "Ecuador"}, + { "TG", "Jamaica"}, + { "TH", "Guatemala"}, + { "TL", "Haiti"}, + { "TM", "Honduras"}, + { "TP", "Nicaragua"}, + { "TQ", "Panama"}, + { "TR", "Panama"}, + { "TS", "El Salvador"}, + { "UA", "Argentina"}, + { "UE", "Bolivia"}, + { "UF", "Brazil"}, + { "UH", "Chile"}, + { "UL", "Colombia"}, + { "UN", "Paraguay"}, + { "UP", "Peru"}, + { "US", "Uruguay"}, + { "UT", "Venezuela"}, + { "VA", "Argentina"}, + { "VF", "Brazil"}, + { "VH", "Chile"}, + { "VL", "Colombia"}, + { "VN", "Paraguay"}, + { "VP", "Peru"}, + { "VS", "Uruguay"}, + { "VT", "Venezuela"}, + { "XA", "Sovereign Military Order of Malta, Palestine, Arab League"}, + { "XC", "FAO, United Nations, UNIDO, International Organisations, European Union"}, + { "XD", "FAO, United Nations, UNIDO, International Organisations, European Union"}, + { "XE", "FAO, United Nations, UNIDO, International Organisations, European Union"}, + { "XF", "FAO, United Nations, UNIDO, International Organisations, European Union"}, + { "XH", "FAO, United Nations, UNIDO, International Organisations, European Union"}, + { "XG", "Vatican City State"}, + { "ZA", "Australia"}, + { "ZC", "New Zealand "}, + }; + + public virtual Plate TryIdentifyPlate(string plateNumber) + { + var testPlateNumber = plateNumber.Trim().ToUpper().Replace(" ", ""); + + PlateSearchResult result = new PlateSearchResult(); + + Regex regex = new Regex(Pattern, RegexOptions.IgnoreCase); + var match = regex.Match(testPlateNumber); + + if (match.Success && match.Groups.Count > 1) + { + var code = match.Groups[1].Value; + + if (_diplomaticCorpsCodes.ContainsKey(code)) + { + return new DiplomaticPlate() + { + PlateNumber = plateNumber, + Type = PlateType, + DiplomaticDetails = _diplomaticCorpsCodes[code] + }; + } + } + + return null; + } + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/DiplomaticCorpsPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/DiplomaticCorpsPlateIdentifier.cs new file mode 100644 index 0000000..f980ce8 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/DiplomaticCorpsPlateIdentifier.cs @@ -0,0 +1,202 @@ +using System.Collections.Generic; +using System.Text.RegularExpressions; +using ItalianToolkit.Transports.Models; + +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class DiplomaticCorpsPlateIdentifier : IPlatesIdentifierPlugin + { + public PlateType PlateType => PlateType.DiplomaticCorps; + + public string Pattern => @"^[cC][dD][0-9]{3}([A-Za-z]{2})\b$"; + + private readonly Dictionary _diplomaticCorpsCodes = new Dictionary() + { + { "AA", "Albania" }, + {"AC", "Austria"}, + {"AE", "Belgium"}, + { "AG", "Bulgaria"}, + { "AK", "Czech Republic"}, + { "AM", "Cyprus"}, + { "AN", "Denmark"}, + { "AP", "Finland"}, + { "AQ", "France"}, + { "AU", "Germany"}, + { "BC", "Great Britain"}, + { "BF", "Slovenia"}, + { "BG", "Greece"}, + { "BM", "Ireland"}, + { "BN", "Italy (Holy See)"}, + { "BP", "Serbia"}, + { "BQ", "Croatia"}, + { "BR", "Luxembourg"}, + { "BS", "Malta"}, + { "BT", "Monaco"}, + { "BV", "Norway"}, + { "BX", "Netherlands"}, + { "CA", "Poland"}, + { "CC", "Portugal"}, + { "CE", "Romania"}, + { "CG", "San Marino"}, + { "CH", "Spain"}, + { "CQ", "Switzerland"}, + { "CN", "Sweden"}, + { "CR", "Turkey"}, + { "CX", "Hungary"}, + { "DA", "Russian Federation"}, + { "DC", "the Ukraine"}, + { "DD", "Uzbekistan"}, + { "DE", "Vatican City State (Apostolic Nunciature)"}, + { "DF", "Estonia"}, + { "DG", "Macedonia"}, + { "DH", "Bosnia-Herzegovina"}, + { "DL", "Slovakian Republic"}, + { "DM", "Armenia"}, + { "DN", "Georgia"}, + { "DP", "Kazakhstan"}, + { "DQ", "Latvia"}, + { "DR", "Belarus"}, + { "DS", "Lithuania"}, + { "DT", "Moldava"}, + { "DV", "Iceland"}, + { "DZ", "Azerbaijan"}, + { "EA", "Burkina Faso"}, + { "EB", "Dominica"}, + { "EC", "Uganda"}, + { "ED", "Burundi"}, + { "EF", "Rwanda"}, + { "EG", "Zimbawe"}, + { "EH", "Qatar"}, + { "EL", "Chad"}, + { "EM", "Mauritania"}, + { "EN", "Eritrea"}, + { "EP", "Mali"}, + { "ER", "Belize"}, + { "ES", "Equatorial Guinea c/o FAO"}, + { "ET", "Kosovo"}, + { "EU", "Benin"}, + { "GA", "Afghanistan"}, + { "GB", "Saudi Arabia"}, + { "GC", "Bangladesh"}, + { "GD", "Myanmar"}, + { "GE", "Taiwan"}, + { "GF", "China"}, + { "GL", "North Korea"}, + { "GM", "Korea"}, + { "GP", "Arab Emirates"}, + { "GQ", "Philippines"}, + { "GS", "Japan"}, + { "GZ", "Jordan"}, + { "HA", "India"}, + { "HC", "Indonesia"}, + { "HE", "Iran"}, + { "HF", "Iraq"}, + { "HL", "Israel"}, + { "HQ", "Kuwait"}, + { "HR", "Lebanon"}, + { "HS", "Malaysia"}, + { "HT", "Oman"}, + { "HV", "Pakistan"}, + { "HX", "Syria"}, + { "LA", "Sri Lanka"}, + { "LB", "Thailand"}, + { "LE", "Vietnam"}, + { "LF", "Yemen"}, + { "LH", "Montenegro"}, + { "LM", "East Timor"}, + { "NA", "Algeria"}, + { "NC", "Angola"}, + { "ND", "Cameroon"}, + { "NF", "Cape Verde"}, + { "NG", "Central African Republic"}, + { "NH", "Republic of Congo"}, + { "NL", "Ivory Coast"}, + { "NM", "Egypt"}, + { "NR", "Ethiopia"}, + { "NT", "Gabon"}, + { "NX", "Ghana"}, + { "PA", "Guinea"}, + { "PB", "Kenya"}, + { "PC", "Lesotho"}, + { "PD", "Liberia"}, + { "PE", "Libya"}, + { "PL", "Madagascar"}, + { "PN", "Morocco"}, + { "PQ", "Nigeria"}, + { "PS", "Senegal"}, + { "PT", "Sierra Leone"}, + { "PV", "Mozambico"}, + { "PX", "Somalia"}, + { "QA", "South Africa"}, + { "QC", "Sudan"}, + { "QE", "Tanzania"}, + { "QG", "Tunisia"}, + { "QL", "Democratic Republic of Congo"}, + { "QN", "Zambia"}, + { "QP", "Niger"}, + { "SA", "Canada"}, + { "SD", "Mexico"}, + { "SF", "United States of America"}, + { "SH", "United States of America"}, + { "SL", "United States of America"}, + { "SN", "United States of America"}, + { "SQ", "United States of America"}, + { "TA", "Costa Rica"}, + { "TC", "Cuba"}, + { "TE", "Dominican Republic"}, + { "TF", "Ecuador"}, + { "TG", "Jamaica"}, + { "TH", "Guatemala"}, + { "TL", "Haiti"}, + { "TM", "Honduras"}, + { "TP", "Nicaragua"}, + { "TQ", "Panama"}, + { "TS", "El Salvador"}, + { "UA", "Argentina"}, + { "UE", "Bolivia"}, + { "UF", "Brazil"}, + { "UH", "Chile"}, + { "UL", "Colombia"}, + { "UN", "Paraguay"}, + { "UP", "Peru"}, + { "US", "Uruguay"}, + { "UT", "Venezuela"}, + { "XA", "Sovereign Military Order of Malta, Palestine, Arab League"}, + { "XC", "FAO, United Nations, UNIDO, International Organisations, European Union"}, + { "XD", "FAO, United Nations, UNIDO, International Organisations, European Union"}, + { "XE", "FAO, United Nations, UNIDO, International Organisations, European Union"}, + { "XF", "FAO, United Nations, UNIDO, International Organisations, European Union"}, + { "XH", "FAO, United Nations, UNIDO, International Organisations, European Union"}, + { "XG", "Vatican City State"}, + { "ZA", "Australia"}, + { "ZC", "New Zealand "}, + }; + + public virtual Plate TryIdentifyPlate(string plateNumber) + { + var testPlateNumber = plateNumber.Trim().ToUpper().Replace(" ", ""); + + PlateSearchResult result = new PlateSearchResult(); + + Regex regex = new Regex(Pattern, RegexOptions.IgnoreCase); + var match = regex.Match(testPlateNumber); + + if (match.Success && match.Groups.Count > 1) + { + var code = match.Groups[1].Value; + + if (_diplomaticCorpsCodes.ContainsKey(code)) + { + return new DiplomaticPlate() + { + PlateNumber = plateNumber, + Type = PlateType, + DiplomaticDetails = _diplomaticCorpsCodes[code] + }; + } + } + + return null; + } + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/FinanceGuardPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/FinanceGuardPlateIdentifier.cs new file mode 100644 index 0000000..9b63609 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/FinanceGuardPlateIdentifier.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using ItalianToolkit.Transports.Models; + +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class FinanceGuardPlateIdentifier : RegexMultiPlateIdentifier + { + public override Dictionary Patterns => new Dictionary() + { + { + PlateType.FinanceGuard, + @"^[gG][dD][iI][fF]\d{3}[A-HJ-NPR-TV-Za-hj-npr-tv-z]{2}\b$" + },{ + PlateType.FinanceGuardMotorbike, + @"^[gG].?[dD][iI][fF].?[1][0-1]\d{3}\b$" + },{ + PlateType.FinanceGuardTrailer, + @"^[gG].?[dD][iI][fF].?\d{3}[rR]\b$" + } + }; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/FireFightersBolzanoPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/FireFightersBolzanoPlateIdentifier.cs new file mode 100644 index 0000000..67dd618 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/FireFightersBolzanoPlateIdentifier.cs @@ -0,0 +1,9 @@ +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class FireFightersBolzanoPlateIdentifier : RegexPlateIdentifier + { + public override Models.PlateType PlateType => Models.PlateType.FireFightersBolzano; + + public override string Pattern => @"^[vV][fF][fF][wW][A-Za-z0-9]{3}\b$"; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/FireFightersPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/FireFightersPlateIdentifier.cs new file mode 100644 index 0000000..7081d4c --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/FireFightersPlateIdentifier.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using ItalianToolkit.Transports.Models; + +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class FireFightersPlateIdentifier : RegexMultiPlateIdentifier + { + public override Dictionary Patterns => new Dictionary() + { + { + PlateType.FireFighters, + @"^[vV][fF][0-9]{5}\b$" + },{ + PlateType.FireFightersTrailer, + @"^[vV][fF][rR][0-9]{4}\b$" + },{ + PlateType.FireFightersTestVehicle, + @"^[vV][fF][pR][0-9]{5}\b$" + } + }; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/FireFightersTrentoPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/FireFightersTrentoPlateIdentifier.cs new file mode 100644 index 0000000..9545e1c --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/FireFightersTrentoPlateIdentifier.cs @@ -0,0 +1,9 @@ +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class FireFightersTrentoPlateIdentifier : RegexPlateIdentifier + { + public override Models.PlateType PlateType => Models.PlateType.FireFightersTrento; + + public override string Pattern => @"^[vV][fF][A-Za-z0-9]{3}[tT][nN]\b$"; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ForeignExcursionistsPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ForeignExcursionistsPlateIdentifier.cs new file mode 100644 index 0000000..9cb16e1 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ForeignExcursionistsPlateIdentifier.cs @@ -0,0 +1,8 @@ +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class ForeignExcursionistsPlateIdentifier : RegexPlateIdentifier + { + public override Models.PlateType PlateType => Models.PlateType.ForeignExcursionists; + public override string Pattern => @"^[eE][eE]\d{3}[A-HJ-NPR-TV-Za-hj-npr-tv-z]{2}\b$"; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ForestryCorpsAostaValleyPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ForestryCorpsAostaValleyPlateIdentifier.cs new file mode 100644 index 0000000..aa371c0 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ForestryCorpsAostaValleyPlateIdentifier.cs @@ -0,0 +1,9 @@ +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class ForestryCorpsAostaValleyPlateIdentifier : RegexPlateIdentifier + { + public override Models.PlateType PlateType => Models.PlateType.ForestryCorpsAosta; + + public override string Pattern => @"^[cC][fF][A-Za-z0-9]{3}[aA][oO]\b$"; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ForestryCorpsBolzanoPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ForestryCorpsBolzanoPlateIdentifier.cs new file mode 100644 index 0000000..2079229 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ForestryCorpsBolzanoPlateIdentifier.cs @@ -0,0 +1,9 @@ +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class ForestryCorpsBolzanoPlateIdentifier : RegexPlateIdentifier + { + public override Models.PlateType PlateType => Models.PlateType.ForestryCorpsBolzano; + + public override string Pattern => @"^[cC][fF][fF][dD][A-Za-z0-9]{3}\b$"; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ForestryCorpsFriuliPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ForestryCorpsFriuliPlateIdentifier.cs new file mode 100644 index 0000000..549cfe2 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ForestryCorpsFriuliPlateIdentifier.cs @@ -0,0 +1,9 @@ +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class ForestryCorpsFriuliPlateIdentifier : RegexPlateIdentifier + { + public override Models.PlateType PlateType => Models.PlateType.ForestryCorpsFriuli; + + public override string Pattern => @"^[cC][fF][A-Za-z0-9]{3}\b$"; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ForestryCorpsPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ForestryCorpsPlateIdentifier.cs new file mode 100644 index 0000000..7bccb7a --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ForestryCorpsPlateIdentifier.cs @@ -0,0 +1,9 @@ +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class ForestryCorpsPlateIdentifier : RegexPlateIdentifier + { + public override Models.PlateType PlateType => Models.PlateType.ForestryCorps; + + public override string Pattern => @"^[cC][fF][sS]\d{3}[A-HJ-NPR-TV-Za-hj-npr-tv-z]{2}\b$"; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ForestryCorpsSardiniaPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ForestryCorpsSardiniaPlateIdentifier.cs new file mode 100644 index 0000000..e4be770 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ForestryCorpsSardiniaPlateIdentifier.cs @@ -0,0 +1,40 @@ +using System.Collections.Generic; +using ItalianToolkit.Transports.Models; + +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class ForestryCorpsSardiniaPlateIdentifier : RegexMultiPlateIdentifier + { + public override Dictionary Patterns => new Dictionary() + { + { + PlateType.ForestryCorpsCagliari, + @"^[cC][fF][vV][aA][A-Za-z0-9]{3}[cC][aA]\b$" + },{ + PlateType.ForestryCorpsCarboniaIglesias, + @"^[cC][fF][vV][aA][A-Za-z0-9]{3}[cC][iI]\b$" + },{ + PlateType.ForestryCorpsMedioCampidano, + @"^[cC][fF][vV][aA][A-Za-z0-9]{3}[vV][sS]\b$" + },{ + PlateType.ForestryCorpsNuoro, + @"^[cC][fF][vV][aA][A-Za-z0-9]{3}[nN][uU]\b$" + },{ + PlateType.ForestryCorpsOgliastra, + @"^[cC][fF][vV][aA][A-Za-z0-9]{3}[oO][gG]\b$" + },{ + PlateType.ForestryCorpsOlbiaTempio, + @"^[cC][fF][vV][aA][A-Za-z0-9]{3}[oO][tT]\b$" + },{ + PlateType.ForestryCorpsOristano, + @"^[cC][fF][vV][aA][A-Za-z0-9]{3}[oO][rR]\b$" + },{ + PlateType.ForestryCorpsSassari, + @"^[cC][fF][vV][aA][A-Za-z0-9]{3}[sS][sS]\b$" + },{ + PlateType.ForestryCorpsSudSardegna, + @"^[cC][fF][vV][aA][A-Za-z0-9]{3}[sS][uU]\b$" + } + }; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ForestryCorpsSicillyPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ForestryCorpsSicillyPlateIdentifier.cs new file mode 100644 index 0000000..b761c05 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ForestryCorpsSicillyPlateIdentifier.cs @@ -0,0 +1,40 @@ +using System.Collections.Generic; +using ItalianToolkit.Transports.Models; + +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class ForestryCorpsSicillyPlateIdentifier : RegexMultiPlateIdentifier + { + public override Dictionary Patterns => new Dictionary() + { + { + PlateType.ForestryCorpsAgrigento, + @"^[cC][fF][A-Za-z0-9]{3}[aA][gG]\b$" + },{ + PlateType.ForestryCorpsCaltanissetta, + @"^[cC][fF][A-Za-z0-9]{3}[cC][lL]\b$" + },{ + PlateType.ForestryCorpsCatania, + @"^[cC][fF][A-Za-z0-9]{3}[cC][tT]\b$" + },{ + PlateType.ForestryCorpsEnna, + @"^[cC][fF][A-Za-z0-9]{3}[eE][nN]\b$" + },{ + PlateType.ForestryCorpsMessina, + @"^[cC][fF][A-Za-z0-9]{3}[mM][eE]\b$" + },{ + PlateType.ForestryCorpsPalermo, + @"^[cC][fF][A-Za-z0-9]{3}[pP][aA]\b$" + },{ + PlateType.ForestryCorpsRagusa, + @"^[cC][fF][A-Za-z0-9]{3}[rR][gG]\b$" + },{ + PlateType.ForestryCorpsSiracusa, + @"^[cC][fF][A-Za-z0-9]{3}[sS][rR]\b$" + },{ + PlateType.ForestryCorpsTrapani, + @"^[cC][fF][A-Za-z0-9]{3}[tT][pP]\b$" + } + }; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ForestryCorpsTrentoPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ForestryCorpsTrentoPlateIdentifier.cs new file mode 100644 index 0000000..96ae3e4 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ForestryCorpsTrentoPlateIdentifier.cs @@ -0,0 +1,9 @@ +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class ForestryCorpsTrentoPlateIdentifier : RegexPlateIdentifier + { + public override Models.PlateType PlateType => Models.PlateType.ForestryCorpsTrento; + + public override string Pattern => @"^[cC][fF][A-Za-z0-9]{3}[tT][nN]\b$"; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/IPlatesIdentifierPlugin.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/IPlatesIdentifierPlugin.cs new file mode 100644 index 0000000..a679f79 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/IPlatesIdentifierPlugin.cs @@ -0,0 +1,9 @@ +using ItalianToolkit.Transports.Models; + +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public interface IPlatesIdentifierPlugin + { + Plate TryIdentifyPlate(string identifier); + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ItalianAirForcePlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ItalianAirForcePlateIdentifier.cs new file mode 100644 index 0000000..972b7af --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ItalianAirForcePlateIdentifier.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using ItalianToolkit.Transports.Models; + +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class ItalianAirForcePlateIdentifier : RegexMultiPlateIdentifier + { + public override Dictionary Patterns => new Dictionary() + { + { + PlateType.ItalianAirForce, + @"^[aA][mM]([Aa][Hh][5-9][0-9]{2}|[Aa][Ii][0-9]{3}|[B-Zb-z][A-Za-z][0-9]{3})\b$" + },{ + PlateType.ItalianAirForceMotorbike, + @"^[aA][mM]([Aa]\/[6-9][0-9]{3}|[B-Zb-z]\/[0-9]{4})\b$" + }, + }; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ItalianArmyPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ItalianArmyPlateIdentifier.cs new file mode 100644 index 0000000..bba11da --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ItalianArmyPlateIdentifier.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; +using ItalianToolkit.Transports.Models; + +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class ItalianArmyPlateIdentifier : RegexMultiPlateIdentifier + { + public override Dictionary Patterns => new Dictionary() + { + { + PlateType.ItalianArmyHistoricalVehicle, + @"^[eE][iI][vV][sS][0-9]{3}\b$" + },{ + PlateType.ItalianArmy, + @"^[eE][iI][A-Za-z]{2}[0-9]{3}\b$" + },{ + PlateType.ItalianArmyTrailer, + @"^[rR][iI][mM][oO][rR][cC][hH][iI][oO][eE][iI][A-Za-z]{2}[0-9]{2}\b$" + },{ + PlateType.ItalianArmyMotorbike, + @"^[eE][iI][A-Za-z][0-9]{4}\b$" + },{ + PlateType.ItalianArmyTank, + @"^[eE][iI][0-8][0-9]{5}\b$" + } + }; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ItalianNavyPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ItalianNavyPlateIdentifier.cs new file mode 100644 index 0000000..2568d47 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ItalianNavyPlateIdentifier.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using ItalianToolkit.Transports.Models; + +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class ItalianNavyPlateIdentifier : RegexMultiPlateIdentifier + { + public override Dictionary Patterns => new Dictionary() + { + { + PlateType.ItalianNavy, + @"^[mM]{2}[A-Za-z]{2}[0-9]{3}\b$" + },{ + PlateType.ItalianNavyTrailer, + @"^[rR][iI][mM][oO][rR][cC][hH][iI][oO][mM]{2}[A-Za-z]{2}[0-9]{3}\b$" + } + }; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ItalianRedCrossMotorbikePlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ItalianRedCrossMotorbikePlateIdentifier.cs new file mode 100644 index 0000000..0add939 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ItalianRedCrossMotorbikePlateIdentifier.cs @@ -0,0 +1,9 @@ +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class ItalianRedCrossMotorbikePlateIdentifier : RegexPlateIdentifier + { + public override Models.PlateType PlateType => Models.PlateType.ItalianRedCrossMotorbike; + + public override string Pattern => @"^[cC][rR][iI]\d{3,4}\b$"; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ItalianRedCrossPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ItalianRedCrossPlateIdentifier.cs new file mode 100644 index 0000000..ba4b4d7 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/ItalianRedCrossPlateIdentifier.cs @@ -0,0 +1,9 @@ +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class ItalianRedCrossPlateIdentifier : RegexPlateIdentifier + { + public override Models.PlateType PlateType => Models.PlateType.ItalianRedCross; + + public override string Pattern => @"^[cC][rR][iI][A-HJ-NPR-TV-Za-hj-npr-tv-z0-9]{5}\b$"; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/LocalPolicePlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/LocalPolicePlateIdentifier.cs new file mode 100644 index 0000000..a18cc46 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/LocalPolicePlateIdentifier.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using ItalianToolkit.Transports.Models; + +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class LocalPolicePlateIdentifier : RegexMultiPlateIdentifier + { + public override Dictionary Patterns => new Dictionary() + { + { + PlateType.LocalPolice, + @"^[pP][oO][lL][iI][zZ][iI][aA][lL][oO][cC][aA][lL][eE][yY][A-Za-z][0-9]{3}[A-Za-z]{2}\b$" + },{ + PlateType.LocalPoliceMotorcycle, + @"^[pP][oO][lL][iI][zZ][iI][aA][lL][oO][cC][aA][lL][eE][yY][A-Za-z][0-9]{5}\b$" + },{ + PlateType.LocalPoliceMotorbike, + @"^[pP][oO][lL][iI][zZ][iI][aA][lL][oO][cC][aA][lL][eE][yY][0-9]{3}[A-Za-z]{2}\b$" + } + }; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/MotorbikePlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/MotorbikePlateIdentifier.cs new file mode 100644 index 0000000..6acf207 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/MotorbikePlateIdentifier.cs @@ -0,0 +1,33 @@ +using System.Text.RegularExpressions; +using ItalianToolkit.Transports.Models; + +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class MotorbikePlateIdentifier : IPlatesIdentifierPlugin + { + public PlateType PlateType => PlateType.Motorbike; + public string Pattern => @"^(?!EE)(?!Ee)(?!eE)(?!ee)[A-HJ-NPR-TV-Za-hj-npr-tv-z]{2}\d{5}\b$"; + + public virtual Plate TryIdentifyPlate(string plateNumber) + { + var testPlateNumber = plateNumber.Trim().ToUpper().Replace(" ", ""); + + PlateSearchResult result = new PlateSearchResult(); + + Regex regex = new Regex(Pattern, RegexOptions.IgnoreCase); + if (regex.IsMatch(testPlateNumber)) + { + // TODO: match first group, and exclude it if ambigouos with old provinces codes + // e.g. AN12345 is formally valid, but can't use AN -> old Ancona code + + return new Plate() + { + PlateNumber = plateNumber, + Type = PlateType + }; + } + + return null; + } + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/MotorcyclePlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/MotorcyclePlateIdentifier.cs new file mode 100644 index 0000000..ef8a0f9 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/MotorcyclePlateIdentifier.cs @@ -0,0 +1,8 @@ +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class MotorcyclePlateIdentifier : RegexPlateIdentifier + { + public override Models.PlateType PlateType => Models.PlateType.Motorcycle; + public override string Pattern => @"^[B-DF-HJ-NPR-TV-Zb-df-hj-npr-tv-z2-9]{6}\b$"; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/PenitentiaryPolicePlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/PenitentiaryPolicePlateIdentifier.cs new file mode 100644 index 0000000..08f7cde --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/PenitentiaryPolicePlateIdentifier.cs @@ -0,0 +1,8 @@ +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class PenitentiaryPolicePlateIdentifier : RegexPlateIdentifier + { + public override Models.PlateType PlateType => Models.PlateType.PenitentiaryPolice; + public override string Pattern => @"^[pP][oO][lL][iI][zZ][iI][aA][pP][eE][nN][iI][tT][eE][nN][zZ][iI][aA][rR][iI][aA]\d{3}[A-Za-z]{2}\b$"; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/RegexMultiPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/RegexMultiPlateIdentifier.cs new file mode 100644 index 0000000..182538c --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/RegexMultiPlateIdentifier.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; +using System.Text.RegularExpressions; +using ItalianToolkit.Transports.Models; + +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public abstract class RegexMultiPlateIdentifier : IPlatesIdentifierPlugin + { + public virtual Dictionary Patterns => new Dictionary(); + + public virtual Plate TryIdentifyPlate(string plateNumber) + { + var testPlateNumber = plateNumber.Trim().ToUpper().Replace(" ", ""); + + Plate res = null; + + foreach (var pattern in Patterns) + { + Regex regex = new Regex(pattern.Value, RegexOptions.IgnoreCase); + if (regex.IsMatch(testPlateNumber)) + { + res = new Plate() + { + PlateNumber = plateNumber, + Type = pattern.Key + }; + + break; + } + } + + return res; + } + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/RegexPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/RegexPlateIdentifier.cs new file mode 100644 index 0000000..cf3eb3c --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/RegexPlateIdentifier.cs @@ -0,0 +1,31 @@ +using System.Text.RegularExpressions; +using ItalianToolkit.Transports.Models; + +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public abstract class RegexPlateIdentifier : IPlatesIdentifierPlugin + { + public virtual PlateType PlateType { get; } + public virtual string Pattern { get; } + + public virtual Plate TryIdentifyPlate(string plateNumber) + { + var testPlateNumber = plateNumber.Trim().ToUpper().Replace(" ", ""); + + PlateSearchResult result = new PlateSearchResult(); + + Regex regex = new Regex(Pattern, RegexOptions.IgnoreCase); + if (regex.IsMatch(testPlateNumber)) + { + + return new Plate() + { + PlateNumber = plateNumber, + Type = PlateType + }; + } + + return null; + } + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/SovereignMilitaryOrderOfMaltaPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/SovereignMilitaryOrderOfMaltaPlateIdentifier.cs new file mode 100644 index 0000000..a37b97e --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/SovereignMilitaryOrderOfMaltaPlateIdentifier.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using ItalianToolkit.Transports.Models; + +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class SovereignMilitaryOrderOfMaltaPlateIdentifier : RegexMultiPlateIdentifier + { + public override Dictionary Patterns => new Dictionary() + { + { + PlateType.SovereignMilitaryOrderOfMalta, + @"^[sS][mM][oO][mM]\d{3}\b$" + },{ + PlateType.SovereignMilitaryOrderOfMaltaMotorbike, + @"^[sS][mM][oO][mM]{2}\d{3}\b$" + } + }; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/StatePolicePlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/StatePolicePlateIdentifier.cs new file mode 100644 index 0000000..e4e1969 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/StatePolicePlateIdentifier.cs @@ -0,0 +1,8 @@ +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class StatePolicePlateIdentifier : RegexPlateIdentifier + { + public override Models.PlateType PlateType => Models.PlateType.StatePolice; + public override string Pattern => @"^[pP][oO][lL][iI][zZ][iI][aA][A-Za-z]\d{4}\b$"; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/TestVehiclesPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/TestVehiclesPlateIdentifier.cs new file mode 100644 index 0000000..e7e3c43 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/TestVehiclesPlateIdentifier.cs @@ -0,0 +1,9 @@ +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class TestVehiclesPlateIdentifier : RegexPlateIdentifier + { + public override Models.PlateType PlateType => Models.PlateType.TestVehicle; + + public override string Pattern => @"^[A-Za-z0-9]{2}[pP][A-Za-z0-9]{5}\b$"; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/TrailerPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/TrailerPlateIdentifier.cs new file mode 100644 index 0000000..2b41761 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/TrailerPlateIdentifier.cs @@ -0,0 +1,8 @@ +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class TrailerPlateIdentifier : RegexPlateIdentifier + { + public override Models.PlateType PlateType => Models.PlateType.Trailer; + public override string Pattern => @"^[X][A-HJ-NPR-TV-Za-hj-npr-tv-z]\d{3}[A-HJ-NPR-TV-Za-hj-npr-tv-z]{2}\b$"; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/UnitedNationsPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/UnitedNationsPlateIdentifier.cs new file mode 100644 index 0000000..1a64211 --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/UnitedNationsPlateIdentifier.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using ItalianToolkit.Transports.Models; + +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class UnitedNationsPlateIdentifier : RegexMultiPlateIdentifier + { + public override Dictionary Patterns => new Dictionary() + { + { + PlateType.UnitedNations, + @"^[uU][nN]\d{3}[A-Za-z]{2}\b$" + },{ + PlateType.UnitedNationsStaff, + @"^[uU][nN][pP]\d{3}[A-Za-z]{2}\b$" + },{ + PlateType.UnitedNationsInTransit, + @"^[uU][nN][tT]\d{3}[A-Za-z]{2}\b$" + } + }; + } +} diff --git a/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/WellKnownVehiclesPlateIdentifier.cs b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/WellKnownVehiclesPlateIdentifier.cs new file mode 100644 index 0000000..202c50d --- /dev/null +++ b/src/ItalianToolkit/Transports/PlatesIdentifierPlugins/WellKnownVehiclesPlateIdentifier.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; +using ItalianToolkit.Transports.Models; + +namespace ItalianToolkit.Transports.PlatesIdentifierPlugins +{ + public class WellKnownVehiclesPlateIdentifier : IPlatesIdentifierPlugin + { + private struct KnownPlateData + { + public KnownPlateData(PlateType type, string details) + { + Type = type; + Details = details; + } + + public PlateType Type { get; } + + public string Details { get; } + } + + private readonly Dictionary _wellKnownPlates = new Dictionary() + { + { "EY897ZX", new KnownPlateData(PlateType.LocalPolice, "Ferrari 458 - Polizia Locale di Milano")}, + { "POLIZIALOCALEEY897ZX", new KnownPlateData(PlateType.LocalPolice, "Ferrari 458 - Polizia Locale di Milano")}, + { "POLIZIAM2658", new KnownPlateData(PlateType.StatePolice, "Lamborghini Huracán LP-610")}, + { "POLIZIAH8862", new KnownPlateData(PlateType.StatePolice, "Lamborghini Huracán LP-610")}, + { "POLIZIAE8300", new KnownPlateData(PlateType.StatePolice, "Lamborghini Gallardo")}, + { "POLIZIAF8743", new KnownPlateData(PlateType.StatePolice, "Lamborghini Gallardo")}, + }; + + public virtual Plate TryIdentifyPlate(string plateNumber) + { + var testPlateNumber = plateNumber.Trim().ToUpper().Replace(" ", ""); + + if (_wellKnownPlates.ContainsKey(testPlateNumber)) + { + var wellKnowPlate = _wellKnownPlates[testPlateNumber]; + + return new WellKnownPlate() + { + PlateNumber = plateNumber, + Type = wellKnowPlate.Type, + Details = wellKnowPlate.Details + }; + } + + return null; + } + } +} diff --git a/src/ItalianToolkit/version.json b/src/ItalianToolkit/version.json index 85f827b..17abbee 100644 --- a/src/ItalianToolkit/version.json +++ b/src/ItalianToolkit/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "1.1", + "version": "1.2", "versionHeightOffset": -1, "publicReleaseRefSpec": [ "^refs/heads/maindolino$" // we release out of master