toString())->toBe('en'); expect((string) $locale)->toBe('en'); }); it('accepts locale with region', function () { $locale = Locale::fromString('en-US'); expect($locale->toString())->toBe('en-US'); expect($locale->getLanguage())->toBe('en'); expect($locale->getRegion())->toBe('US'); }); it('has factory methods for common locales', function () { expect(Locale::english()->toString())->toBe('en'); expect(Locale::german()->toString())->toBe('de'); expect(Locale::french()->toString())->toBe('fr'); expect(Locale::spanish()->toString())->toBe('es'); }); it('extracts language from locale', function () { expect(Locale::fromString('en')->getLanguage())->toBe('en'); expect(Locale::fromString('en-US')->getLanguage())->toBe('en'); expect(Locale::fromString('de-CH')->getLanguage())->toBe('de'); }); it('extracts region from locale with region', function () { expect(Locale::fromString('en-US')->getRegion())->toBe('US'); expect(Locale::fromString('de-CH')->getRegion())->toBe('CH'); }); it('returns null for region when locale has no region', function () { expect(Locale::fromString('en')->getRegion())->toBeNull(); expect(Locale::fromString('de')->getRegion())->toBeNull(); }); it('throws exception for invalid locale format', function () { expect(fn () => Locale::fromString('invalid')) ->toThrow(InvalidArgumentException::class, 'Invalid locale format'); expect(fn () => Locale::fromString('EN')) ->toThrow(InvalidArgumentException::class); expect(fn () => Locale::fromString('en-us')) ->toThrow(InvalidArgumentException::class); }); it('can compare two Locales for equality', function () { $locale1 = Locale::fromString('en'); $locale2 = Locale::fromString('en'); $locale3 = Locale::fromString('de'); expect($locale1->equals($locale2))->toBeTrue(); expect($locale1->equals($locale3))->toBeFalse(); $locale4 = Locale::fromString('en-US'); expect($locale1->equals($locale4))->toBeFalse(); }); });