diff options
| -rw-r--r-- | src/RegistrationNumber.php | 123 | ||||
| -rw-r--r-- | tests/RegistrationNumberTest.php | 58 |
2 files changed, 173 insertions, 8 deletions
diff --git a/src/RegistrationNumber.php b/src/RegistrationNumber.php index 346a1c9..abc1364 100644 --- a/src/RegistrationNumber.php +++ b/src/RegistrationNumber.php @@ -144,15 +144,24 @@ final readonly class RegistrationNumber /** * @var string[] */ - private const array SPECIAL_SUFFIXS = [ - '领', '使', '警', '学', '挂', '港', '澳', '试', '超', + private const array AVAILLABLE_SUFFIXS = [ + self::EMBASSY_SUFFIX, + self::CONSULATE_SUFFIX, + self::POLICE_SUFFIX, + self::COACH_SUFFIX, + self::TRAILER_SUFFIX, + self::HONG_KONG_SUFFIX, + self::MACAU_SUFFIX, + self::TEST_SUFFIX, + self::SPECIAL_SUFFIX, ]; /** * @var string[] */ private const array GUANGDONG_Z_SPECIAL_SUFFIXS = [ - '港', '澳', + self::HONG_KONG_SUFFIX, + self::MACAU_SUFFIX, ]; private const string GUANGDONG_PROVINCE = '粤'; @@ -163,12 +172,30 @@ final readonly class RegistrationNumber private const string CONSULATE_SUFFIX = '领'; + private const string POLICE_SUFFIX = '警'; + + private const string COACH_SUFFIX = '学'; + + private const string TRAILER_SUFFIX = '挂'; + + private const string HONG_KONG_SUFFIX = '港'; + + private const string MACAU_SUFFIX = '澳'; + + private const string TEST_SUFFIX = '试'; + + private const string SPECIAL_SUFFIX = '超'; + public string $region; + public string $agencyNumber; + public string $authority; public string $sequence; + public string $suffix; + private function __construct( public string $registrationNumber ) { @@ -311,7 +338,7 @@ final readonly class RegistrationNumber $last = mb_substr($registrationNumber, -1); - $suffix = in_array($last, self::SPECIAL_SUFFIXS, strict: true) + $suffix = in_array($last, self::AVAILLABLE_SUFFIXS, strict: true) ? $last : ''; @@ -361,7 +388,7 @@ final readonly class RegistrationNumber && $authority === self::GUANGDONG_SPECIAL_AUTHORITY; } - if ($suffix !== '' && ! in_array($suffix, self::SPECIAL_SUFFIXS, strict: true)) { + if ($suffix !== '' && ! in_array($suffix, self::AVAILLABLE_SUFFIXS, strict: true)) { $len = mb_strlen($sequence); return $len >= 4 && $len <= 5; @@ -505,9 +532,89 @@ final readonly class RegistrationNumber private function parse(string $registrationNumber): void { - $this->region = mb_substr($registrationNumber, 0, 1); - $this->authority = mb_substr($registrationNumber, 1, 1); - $this->sequence = mb_substr($registrationNumber, 2); + $registrationNumber = mb_strtoupper($registrationNumber); + + $last = mb_substr($registrationNumber, -1); + + match ($last) { + self::EMBASSY_SUFFIX => $this->parseEmbassyRegistrationNumber($registrationNumber), + self::CONSULATE_SUFFIX => $this->parseConsulateRegistrationNumber($registrationNumber), + default => $this->parseRegistrationNumber($registrationNumber), + }; + } + + private function parseEmbassyRegistrationNumber(string $registrationNumber): void + { + [$agency, $sequence, $suffix] = static::extractEmbassyComponents($registrationNumber); + + $this->agencyNumber = $agency; + $this->sequence = $sequence; + $this->suffix = $suffix; + } + + private function parseConsulateRegistrationNumber(string $registrationNumber): void + { + [$region, $agency, $sequence, $suffix] = static::extractConsulateComponents($registrationNumber); + + $this->region = $region; + $this->agencyNumber = $agency; + $this->sequence = $sequence; + $this->suffix = $suffix; + } + + private function parseRegistrationNumber(string $registrationNumber): void + { + [$region, $authority, $sequence, $suffix] = static::extractComponents($registrationNumber); + + $this->region = $region; + $this->authority = $authority; + $this->sequence = $sequence; + $this->suffix = $suffix; + } + + public function isEmbassy(): bool + { + return $this->suffix === self::EMBASSY_SUFFIX; + } + + public function isConsulate(): bool + { + return $this->suffix === self::CONSULATE_SUFFIX; + } + + public function isPolice(): bool + { + return $this->suffix === self::POLICE_SUFFIX; + } + + public function isCoach(): bool + { + return $this->suffix === self::COACH_SUFFIX; + } + + public function isTrailer(): bool + { + return $this->suffix === self::TRAILER_SUFFIX; + } + + public function isFromHongKong(): bool + { + return $this->suffix === self::HONG_KONG_SUFFIX; + } + + public function isFromMacau(): bool + { + return $this->suffix === self::MACAU_SUFFIX; + } + + public function isTest(): bool + { + return $this->suffix === self::TEST_SUFFIX; + } + + public function isSpecial(): bool + { + return $this->suffix === self::SPECIAL_SUFFIX; } public function isCleanEnergy(): bool diff --git a/tests/RegistrationNumberTest.php b/tests/RegistrationNumberTest.php index b014072..9a599b6 100644 --- a/tests/RegistrationNumberTest.php +++ b/tests/RegistrationNumberTest.php @@ -38,6 +38,64 @@ final class RegistrationNumberTest extends TestCase RegistrationNumber::make($registrationNumber); } + public function test_is_embassy_deteremins_if_registration_number_is_used_by_embassies(): void + { + $this->assertTrue(RegistrationNumber::make('224578使')->isEmbassy()); + $this->assertFalse(RegistrationNumber::make('沪22478领')->isEmbassy()); + } + + public function test_is_consulate_determines_if_registration_number_is_used_by_consulates(): void + { + $this->assertTrue(RegistrationNumber::make('沪22478领')->isConsulate()); + $this->assertFalse(RegistrationNumber::make('224578使')->isConsulate()); + } + + public function test_is_police_determines_if_registration_number_is_used_by_police_officers(): void + { + $this->assertTrue(RegistrationNumber::make('京A0006警')->isPolice()); + $this->assertFalse(RegistrationNumber::make('粤E12345学')->isPolice()); + } + + public function test_is_coach_determines_if_registration_number_is_used_by_coaches(): void + { + $this->assertTrue(RegistrationNumber::make('粤E12345学')->isCoach()); + $this->assertFalse(RegistrationNumber::make('粤E12345挂')->isCoach()); + } + + public function test_is_trailer_determines_if_registration_number_is_used_by_trailers(): void + { + $this->assertTrue(RegistrationNumber::make('粤E12345挂')->isTrailer()); + $this->assertFalse(RegistrationNumber::make('粤E12345学')->isTrailer()); + } + + public function test_is_from_hong_kong_determines_if_registration_number_is_used_by_hong_kong_drivers(): void + { + $this->assertTrue(RegistrationNumber::make('粤Z1234港')->isFromHongKong()); + $this->assertTrue(RegistrationNumber::make('粤Z12345港')->isFromHongKong()); + $this->assertFalse(RegistrationNumber::make('粤Z1234澳')->isFromHongKong()); + $this->assertFalse(RegistrationNumber::make('粤Z12345澳')->isFromHongKong()); + } + + public function test_is_from_macau_determines_if_registration_number_is_used_by_macau_drivers(): void + { + $this->assertTrue(RegistrationNumber::make('粤Z1234澳')->isFromMacau()); + $this->assertTrue(RegistrationNumber::make('粤Z12345澳')->isFromMacau()); + $this->assertFalse(RegistrationNumber::make('粤Z1234港')->isFromMacau()); + $this->assertFalse(RegistrationNumber::make('粤Z12345港')->isFromMacau()); + } + + public function test_is_test_determines_if_registration_number_is_used_by_test_vehicles(): void + { + $this->assertTrue(RegistrationNumber::make('粤E12345试')->isTest()); + $this->assertFalse(RegistrationNumber::make('粤E12345学')->isTest()); + } + + public function test_is_special_determines_if_registration_number_is_used_by_special_vehicles(): void + { + $this->assertTrue(RegistrationNumber::make('粤E12345超')->isSpecial()); + $this->assertFalse(RegistrationNumber::make('粤E12345学')->isSpecial()); + } + public function test_is_clean_energy_determines_if_vehicle_is_clean_energy(): void { $this->assertTrue(RegistrationNumber::make('粤ED12345')->isCleanEnergy()); |
