diff --git a/src/Alpha2Code.php b/src/Alpha2Code.php index e5dc4ea..30f9522 100644 --- a/src/Alpha2Code.php +++ b/src/Alpha2Code.php @@ -260,6 +260,11 @@ public function getName(): string return $this->name; } + public function toString(): string + { + return $this->value; + } + /** * Converts this Alpha-2 code to its corresponding Alpha-3 code. * diff --git a/src/Alpha3Code.php b/src/Alpha3Code.php index 56f04e1..ec79575 100644 --- a/src/Alpha3Code.php +++ b/src/Alpha3Code.php @@ -260,6 +260,11 @@ public function getName(): string return $this->name; } + public function toString(): string + { + return $this->value; + } + /** * Converts this Alpha-3 code to its corresponding Alpha-2 code. * diff --git a/src/AlphaCode.php b/src/AlphaCode.php index cfcfc1e..bf249d6 100644 --- a/src/AlphaCode.php +++ b/src/AlphaCode.php @@ -16,4 +16,10 @@ interface AlphaCode * @return string The name of the enum case representing the alpha code. */ public function getName(): string; + + /** + * Gets the alpha code value (e.g. 'BR' for Alpha-2, 'BRA' for Alpha-3). + * @return string The alpha code value. + */ + public function toString(): string; } diff --git a/src/Timezones.php b/src/Timezones.php index 88b17b4..e590c01 100644 --- a/src/Timezones.php +++ b/src/Timezones.php @@ -90,14 +90,14 @@ public function contains(string $iana): bool * Finds a Timezone by its IANA identifier. * * @param string $iana The IANA timezone identifier to search for (e.g. America/Sao_Paulo). - * @return Timezone|null The matching Timezone, or null if not found in this country. + * @return Timezone The matching Timezone, or UTC if not found in this country. */ - public function findByIdentifier(string $iana): ?Timezone + public function findByIdentifier(string $iana): Timezone { return array_find( $this->items, static fn(Timezone $timezone): bool => $timezone->value === $iana - ); + ) ?? Timezone::utc(); } /** diff --git a/tests/CountryTest.php b/tests/CountryTest.php index e860aee..369572e 100644 --- a/tests/CountryTest.php +++ b/tests/CountryTest.php @@ -122,6 +122,26 @@ public function testCountryAlpha3ConvertsToAlpha2Correctly(): void self::assertSame(Alpha3Code::SWITZERLAND, $country->alpha3); } + #[DataProvider('alphaCodeToStringDataProvider')] + public function testCountryAlphaCodeToStringReturnsValue( + Alpha2Code $alpha2, + string $expectedAlpha2String, + string $expectedAlpha3String + ): void { + /** @Given a Country created from an Alpha-2 code */ + $country = Country::from(alphaCode: $alpha2); + + /** @When calling toString on each alpha code */ + $alpha2String = $country->alpha2->toString(); + $alpha3String = $country->alpha3->toString(); + + /** @Then the Alpha-2 toString should return the two-letter code */ + self::assertSame($expectedAlpha2String, $alpha2String); + + /** @And the Alpha-3 toString should return the three-letter code */ + self::assertSame($expectedAlpha3String, $alpha3String); + } + public function testCountryFromStringWithAlpha2Code(): void { /** @Given a valid two-letter alpha code string */ @@ -219,14 +239,11 @@ public function testCountryTimezonesFindByIdentifierReturnsTimezone(): void /** @When searching for a known timezone identifier */ $timezone = $country->timezones->findByIdentifier(iana: 'America/New_York'); - /** @Then a Timezone object should be returned */ - self::assertInstanceOf(Timezone::class, $timezone); - - /** @And its value should match the searched identifier */ + /** @Then the returned Timezone value should match the searched identifier */ self::assertSame('America/New_York', $timezone->value); } - public function testCountryTimezonesFindByIdentifierReturnsNullWhenNotFound(): void + public function testCountryTimezonesFindByIdentifierReturnsUtcWhenNotFound(): void { /** @Given a Country created from Alpha-2 code DE (Germany) */ $country = Country::from(alphaCode: Alpha2Code::GERMANY); @@ -234,8 +251,8 @@ public function testCountryTimezonesFindByIdentifierReturnsNullWhenNotFound(): v /** @When searching for a timezone that does not belong to Germany */ $timezone = $country->timezones->findByIdentifier(iana: 'Asia/Tokyo'); - /** @Then null should be returned */ - self::assertNull($timezone); + /** @Then the fallback UTC timezone should be returned */ + self::assertSame('UTC', $timezone->value); } public function testCountryTimezonesCountMatchesAllSize(): void @@ -299,7 +316,7 @@ public function testCountryWithMultipleTimezonesPreservesAll(): void /** @And each timezone should be findable by its identifier */ foreach ($country->timezones->all() as $timezone) { - self::assertNotNull($country->timezones->findByIdentifier(iana: $timezone->value)); + self::assertSame($timezone->value, $country->timezones->findByIdentifier(iana: $timezone->value)->value); } } @@ -316,7 +333,7 @@ public function testCountryTimezonesCreatedFromSameCodeAreConsistent(): void self::assertSame($first->timezones->count(), $second->timezones->count()); } - public function testCountryWhenInvalidTimezoneIdentifier(): void + public function testCountryWhenInvalidTimezone(): void { /** @Given a non-empty string that is not a valid IANA timezone */ $invalidIdentifier = 'Invalid/Timezone'; @@ -370,48 +387,48 @@ public function testCountryWhenInvalidAlphaCodeImplementation(): void public static function alphaCodeObjectsDataProvider(): array { return [ - 'Alpha2 with custom name' => [ - 'alphaCode' => Alpha2Code::UNITED_STATES_OF_AMERICA, - 'name' => 'United States', - 'expectedName' => 'United States', - 'expectedAlpha2' => Alpha2Code::UNITED_STATES_OF_AMERICA, - 'expectedAlpha3' => Alpha3Code::UNITED_STATES_OF_AMERICA, - ], - 'Alpha3 with custom name' => [ - 'alphaCode' => Alpha3Code::UNITED_STATES_OF_AMERICA, - 'name' => 'United States', - 'expectedName' => 'United States', - 'expectedAlpha2' => Alpha2Code::UNITED_STATES_OF_AMERICA, - 'expectedAlpha3' => Alpha3Code::UNITED_STATES_OF_AMERICA, - ], 'Alpha2 with null name' => [ 'alphaCode' => Alpha2Code::BRAZIL, 'name' => null, 'expectedName' => 'Brazil', 'expectedAlpha2' => Alpha2Code::BRAZIL, - 'expectedAlpha3' => Alpha3Code::BRAZIL, + 'expectedAlpha3' => Alpha3Code::BRAZIL ], 'Alpha3 with null name' => [ 'alphaCode' => Alpha3Code::BRAZIL, 'name' => null, 'expectedName' => 'Brazil', 'expectedAlpha2' => Alpha2Code::BRAZIL, - 'expectedAlpha3' => Alpha3Code::BRAZIL, + 'expectedAlpha3' => Alpha3Code::BRAZIL + ], + 'Alpha2 with custom name' => [ + 'alphaCode' => Alpha2Code::UNITED_STATES_OF_AMERICA, + 'name' => 'United States', + 'expectedName' => 'United States', + 'expectedAlpha2' => Alpha2Code::UNITED_STATES_OF_AMERICA, + 'expectedAlpha3' => Alpha3Code::UNITED_STATES_OF_AMERICA + ], + 'Alpha3 with custom name' => [ + 'alphaCode' => Alpha3Code::UNITED_STATES_OF_AMERICA, + 'name' => 'United States', + 'expectedName' => 'United States', + 'expectedAlpha2' => Alpha2Code::UNITED_STATES_OF_AMERICA, + 'expectedAlpha3' => Alpha3Code::UNITED_STATES_OF_AMERICA ], 'Alpha2 GB with full name' => [ 'alphaCode' => Alpha2Code::UNITED_KINGDOM_OF_GREAT_BRITAIN_AND_NORTHERN_IRELAND, 'name' => 'United Kingdom of Great Britain and Northern Ireland', 'expectedName' => 'United Kingdom of Great Britain and Northern Ireland', 'expectedAlpha2' => Alpha2Code::UNITED_KINGDOM_OF_GREAT_BRITAIN_AND_NORTHERN_IRELAND, - 'expectedAlpha3' => Alpha3Code::UNITED_KINGDOM_OF_GREAT_BRITAIN_AND_NORTHERN_IRELAND, + 'expectedAlpha3' => Alpha3Code::UNITED_KINGDOM_OF_GREAT_BRITAIN_AND_NORTHERN_IRELAND ], 'Alpha3 GBR with null name' => [ 'alphaCode' => Alpha3Code::UNITED_KINGDOM_OF_GREAT_BRITAIN_AND_NORTHERN_IRELAND, 'name' => null, 'expectedName' => 'United Kingdom of Great Britain and Northern Ireland', 'expectedAlpha2' => Alpha2Code::UNITED_KINGDOM_OF_GREAT_BRITAIN_AND_NORTHERN_IRELAND, - 'expectedAlpha3' => Alpha3Code::UNITED_KINGDOM_OF_GREAT_BRITAIN_AND_NORTHERN_IRELAND, - ], + 'expectedAlpha3' => Alpha3Code::UNITED_KINGDOM_OF_GREAT_BRITAIN_AND_NORTHERN_IRELAND + ] ]; } @@ -423,43 +440,74 @@ public static function alphaCodeStringsDataProvider(): array 'name' => 'United States', 'expectedName' => 'United States', 'expectedAlpha2' => Alpha2Code::UNITED_STATES_OF_AMERICA, - 'expectedAlpha3' => Alpha3Code::UNITED_STATES_OF_AMERICA, + 'expectedAlpha3' => Alpha3Code::UNITED_STATES_OF_AMERICA ], 'Alpha3 string USA' => [ 'alphaCode' => 'USA', 'name' => 'United States', 'expectedName' => 'United States', 'expectedAlpha2' => Alpha2Code::UNITED_STATES_OF_AMERICA, - 'expectedAlpha3' => Alpha3Code::UNITED_STATES_OF_AMERICA, + 'expectedAlpha3' => Alpha3Code::UNITED_STATES_OF_AMERICA ], 'Alpha2 string with null name' => [ 'alphaCode' => 'BR', 'name' => null, 'expectedName' => 'Brazil', 'expectedAlpha2' => Alpha2Code::BRAZIL, - 'expectedAlpha3' => Alpha3Code::BRAZIL, + 'expectedAlpha3' => Alpha3Code::BRAZIL ], 'Alpha3 string with null name' => [ 'alphaCode' => 'BRA', 'name' => null, 'expectedName' => 'Brazil', 'expectedAlpha2' => Alpha2Code::BRAZIL, - 'expectedAlpha3' => Alpha3Code::BRAZIL, + 'expectedAlpha3' => Alpha3Code::BRAZIL ], 'Alpha2 string with custom name' => [ 'alphaCode' => 'BR', 'name' => 'Brasil', 'expectedName' => 'Brasil', 'expectedAlpha2' => Alpha2Code::BRAZIL, - 'expectedAlpha3' => Alpha3Code::BRAZIL, + 'expectedAlpha3' => Alpha3Code::BRAZIL ], 'Alpha3 string with custom name' => [ 'alphaCode' => 'BRA', 'name' => 'Brasil', 'expectedName' => 'Brasil', 'expectedAlpha2' => Alpha2Code::BRAZIL, - 'expectedAlpha3' => Alpha3Code::BRAZIL, + 'expectedAlpha3' => Alpha3Code::BRAZIL + ] + ]; + } + + public static function alphaCodeToStringDataProvider(): array + { + return [ + 'Japan' => [ + 'alpha2' => Alpha2Code::JAPAN, + 'expectedAlpha2String' => 'JP', + 'expectedAlpha3String' => 'JPN' + ], + 'Brazil' => [ + 'alpha2' => Alpha2Code::BRAZIL, + 'expectedAlpha2String' => 'BR', + 'expectedAlpha3String' => 'BRA' + ], + 'Germany' => [ + 'alpha2' => Alpha2Code::GERMANY, + 'expectedAlpha2String' => 'DE', + 'expectedAlpha3String' => 'DEU' + ], + 'Switzerland' => [ + 'alpha2' => Alpha2Code::SWITZERLAND, + 'expectedAlpha2String' => 'CH', + 'expectedAlpha3String' => 'CHE' ], + 'United States' => [ + 'alpha2' => Alpha2Code::UNITED_STATES_OF_AMERICA, + 'expectedAlpha2String' => 'US', + 'expectedAlpha3String' => 'USA' + ] ]; } @@ -469,7 +517,7 @@ public static function invalidAlphaCodeStringsDataProvider(): array 'Single character' => ['alphaCode' => 'X'], 'Two characters' => ['alphaCode' => 'XY'], 'Three characters' => ['alphaCode' => 'XYZ'], - 'Four characters' => ['alphaCode' => 'XYZ1'], + 'Four characters' => ['alphaCode' => 'XYZ1'] ]; } } diff --git a/tests/Models/AlphaCodeXpto.php b/tests/Models/AlphaCodeXpto.php index 8dd1eec..ce248a4 100644 --- a/tests/Models/AlphaCodeXpto.php +++ b/tests/Models/AlphaCodeXpto.php @@ -14,4 +14,9 @@ public function getName(): string { return $this->value; } + + public function toString(): string + { + return $this->value; + } }