Skip to content

Commit

Permalink
Add Finder (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
mlocati authored Jul 1, 2024
1 parent 2839985 commit aacb978
Show file tree
Hide file tree
Showing 2 changed files with 357 additions and 0 deletions.
127 changes: 127 additions & 0 deletions src/Finder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<?php

declare(strict_types=1);

namespace MLocati\ComuniItaliani;

class Finder
{
protected Factory $factory;

public function __construct(?Factory $factory = null)
{
$this->factory = $factory ?? new Factory();
}

/**
* Find a territory (Geographical Subdivision, Region, Province, or Municipality) given its ID.
*
* @param int|string|mixed $id int for Geographical Subdivision, string for other territory types.
*/
public function getTerritoryByID($id): ?Territory
{
switch (gettype($id)) {
case 'integer':
return $this->getGeographicalSubdivisionByID($id);
case 'string':
switch (strlen($id)) {
case 2:
return $this->getRegionByID($id);
case 3:
return $this->getProvinceByID($id);
case 6:
return $this->getMunicipalityByID($id);
}
break;
}

return null;
}

/**
* Find a Geographical Subdivision given its ID
*/
public function getGeographicalSubdivisionByID(int $id): ?GeographicalSubdivision
{
foreach ($this->factory->getGeographicalSubdivisions() as $geographicalSubdivision) {
if ($geographicalSubdivision->getID() === $id) {
return $geographicalSubdivision;
}
}

return null;
}

/**
* Find a Region given its ID
*/
public function getRegionByID(string $id): ?Region
{
if (!preg_match('/^[0-9]{2}$/', $id)) {
return null;
}
foreach ($this->factory->getGeographicalSubdivisions() as $geographicalSubdivisions) {
foreach ($geographicalSubdivisions->getRegions() as $region) {
if ($region->getID() === $id) {
return $region;
}
}
}

return null;
}

/**
* Find a Province/UTS given its ID
*
* @param bool $oldIDToo look for $in in historical Province codes too?
*/
public function getProvinceByID(string $id, bool $oldIDToo = false): ?Province
{
if (!preg_match('/^[0-9]{3}$/', $id)) {
return null;
}
foreach ($this->factory->getGeographicalSubdivisions() as $geographicalSubdivisions) {
foreach ($geographicalSubdivisions->getRegions() as $region) {
foreach ($region->getProvinces() as $province) {
foreach ($province->getMunicipalities() as $municipality) {
if ($province->getID() === $id) {
return $province;
}
if ($oldIDToo && $province->getOldID() === $id) {
return $province;
}
}
}
}
}

return null;
}


/**
* Find a Municipality given its ID
*
* @param bool $oldIDToo look for $in in historical Province codes too?
*/
public function getMunicipalityByID(string $id): ?Municipality
{
if (!preg_match('/^[0-9]{6}$/', $id)) {
return null;
}
foreach ($this->factory->getGeographicalSubdivisions() as $geographicalSubdivisions) {
foreach ($geographicalSubdivisions->getRegions() as $region) {
foreach ($region->getProvinces() as $province) {
foreach ($province->getMunicipalities() as $municipality) {
if ($municipality->getID() === $id) {
return $municipality;
}
}
}
}
}

return null;
}
}
230 changes: 230 additions & 0 deletions test/tests/Finder/FindByIDTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
<?php

declare(strict_types=1);

namespace MLocati\ComuniItaliani\Test\Finder;

use MLocati\ComuniItaliani\Finder;
use MLocati\ComuniItaliani\Territory;
use MLocati\ComuniItaliani\GeographicalSubdivision;
use MLocati\ComuniItaliani\Region;
use MLocati\ComuniItaliani\Province;
use PHPUnit\Framework\TestCase;

class FindByIDTest extends TestCase
{
private static ?Finder $finder;

public function provideGetTerritoryByIDCases(): array
{
return [
[null, ''],
[[], ''],
[-1, ''],
[1, 'Nord-ovest'],
[PHP_INT_MAX, ''],
['', ''],
['0', ''],
['1', ''],
['AA', ''],
['00', ''],
['01', 'Piemonte'],
['AAA', ''],
['000', ''],
['258', 'Roma'],
['058', ''],
['215', 'Milano'],
['015', ''],
['AAAA', ''],
['0123', ''],
['AAAAA', ''],
['01234', ''],
['AAAAAA', ''],
['000000', ''],
['058091', 'Roma (RM)'],
['258091', ''],
['015146', 'Milano (MI)'],
['215091', ''],
['0123456', ''],
['AAAAAAA', ''],
];
}

/**
* @dataProvider provideGetTerritoryByIDCases
*/
public function testGetTerritoryByID($id, string $expectedName): void
{
$territory = $this->getFinder()->getTerritoryByID($id);
if ($expectedName === '') {
$this->assertNull($territory);
} else {
$this->assertInstanceOf(Territory::class, $territory);
$this->assertSame($expectedName, (string) $territory);
}
}

public function provideGetGeographicalSubdivisionByIDCases(): array
{
return [
[-1, ''],
[1, 'Nord-ovest'],
[PHP_INT_MAX, ''],
];
}

/**
* @dataProvider provideGetGeographicalSubdivisionByIDCases
*/
public function testGetGeographicalSubdivisionByID(int $id, string $expectedName): void
{
$territory = $this->getFinder()->getGeographicalSubdivisionByID($id);
if ($expectedName === '') {
$this->assertNull($territory);
} else {
$this->assertInstanceOf(GeographicalSubdivision::class, $territory);
$this->assertSame($expectedName, (string) $territory);
}
}

public function provideGetRegionByIDCases(): array
{
return [
['', ''],
['0', ''],
['1', ''],
['AA', ''],
['00', ''],
['01', 'Piemonte'],
['AAA', ''],
['000', ''],
['258', ''],
['058', ''],
['215', ''],
['015', ''],
['AAAA', ''],
['0123', ''],
['AAAAA', ''],
['01234', ''],
['AAAAAA', ''],
['000000', ''],
['058091', ''],
['258091', ''],
['015146', ''],
['215091', ''],
['0123456', ''],
['AAAAAAA', ''],
];
}

/**
* @dataProvider provideGetRegionByIDCases
*/
public function testGetRegionByID(string $id, string $expectedName): void
{
$territory = $this->getFinder()->getRegionByID($id);
if ($expectedName === '') {
$this->assertNull($territory);
} else {
$this->assertInstanceOf(Region::class, $territory);
$this->assertSame($expectedName, (string) $territory);
}
}

public function provideGetProvinceByIDCases(): array
{
return [
['', ''],
['0', ''],
['1', ''],
['AA', ''],
['00', ''],
['01', ''],
['AAA', ''],
['000', ''],
['258', 'Roma'],
['058', ''],
['058', 'Roma', true],
['215', 'Milano'],
['015', ''],
['015', 'Milano', true],
['AAAA', ''],
['0123', ''],
['AAAAA', ''],
['01234', ''],
['AAAAAA', ''],
['000000', ''],
['058091', ''],
['258091', ''],
['015146', ''],
['215091', ''],
['0123456', ''],
['AAAAAAA', ''],
];
}

/**
* @dataProvider provideGetProvinceByIDCases
*/
public function testGetProvinceByID(string $id, string $expectedName, bool $oldIDToo = false): void
{
$territory = $this->getFinder()->getProvinceByID($id, $oldIDToo);
if ($expectedName === '') {
$this->assertNull($territory);
} else {
$this->assertInstanceOf(Province::class, $territory);
$this->assertSame($expectedName, (string) $territory);
}
}


public function provideGetMunicipalityByIDCases(): array
{
return [
['', ''],
['0', ''],
['1', ''],
['AA', ''],
['00', ''],
['01', ''],
['AAA', ''],
['000', ''],
['258', ''],
['058', ''],
['215', ''],
['015', ''],
['AAAA', ''],
['0123', ''],
['AAAAA', ''],
['01234', ''],
['AAAAAA', ''],
['000000', ''],
['058091', 'Roma (RM)'],
['258091', ''],
['015146', 'Milano (MI)'],
['215091', ''],
['0123456', ''],
['AAAAAAA', ''],
];
}

/**
* @dataProvider provideGetMunicipalityByIDCases
*/
public function testGetMunicipalityByID(string $id, string $expectedName): void
{
$territory = $this->getFinder()->getMunicipalityByID($id);
if ($expectedName === '') {
$this->assertNull($territory);
} else {
$this->assertNotNull($territory);
$this->assertSame($expectedName, (string) $territory);
}
}


private function getFinder(): Finder
{
return self::$finder ??= new Finder();
}
}

0 comments on commit aacb978

Please sign in to comment.