value)->toBe('test123'); }); }); describe('POSIX Character Class Validators', function () { it('validates alnum (alphanumeric)', function () { $valid = PosixString::fromString('abc123XYZ'); $invalid = PosixString::fromString('abc-123'); expect($valid->isAlnum())->toBeTrue(); expect($invalid->isAlnum())->toBeFalse(); }); it('validates alpha (alphabetic)', function () { $valid = PosixString::fromString('abcXYZ'); $invalid = PosixString::fromString('abc123'); expect($valid->isAlpha())->toBeTrue(); expect($invalid->isAlpha())->toBeFalse(); }); it('validates alpha with international characters (locale-aware)', function () { // Note: Locale must be set for international character support // setlocale(LC_CTYPE, 'de_DE.UTF-8'); $german = PosixString::fromString('Müller'); $french = PosixString::fromString('Dupré'); $spanish = PosixString::fromString('Señor'); // These work if locale is set // expect($german->isAlpha())->toBeTrue(); // expect($french->isAlpha())->toBeTrue(); // expect($spanish->isAlpha())->toBeTrue(); })->skip('Requires locale configuration'); it('validates ascii', function () { $valid = PosixString::fromString('Hello World!'); $invalid = PosixString::fromString('Hëllö Wörld!'); expect($valid->isAscii())->toBeTrue(); expect($invalid->isAscii())->toBeFalse(); }); it('validates blank (space and tab only)', function () { $valid = PosixString::fromString(" \t "); $invalid = PosixString::fromString(" \n "); expect($valid->isBlank())->toBeTrue(); expect($invalid->isBlank())->toBeFalse(); }); it('validates cntrl (control characters)', function () { $valid = PosixString::fromString("\x00\x01\x02"); $invalid = PosixString::fromString("abc"); expect($valid->isCntrl())->toBeTrue(); expect($invalid->isCntrl())->toBeFalse(); }); it('validates digit', function () { $valid = PosixString::fromString('123456'); $invalid = PosixString::fromString('123abc'); expect($valid->isDigit())->toBeTrue(); expect($invalid->isDigit())->toBeFalse(); }); it('validates graph (visible characters, excluding space)', function () { $valid = PosixString::fromString('Hello!'); $invalid = PosixString::fromString('Hello World'); expect($valid->isGraph())->toBeTrue(); expect($invalid->isGraph())->toBeFalse(); }); it('validates lower (lowercase)', function () { $valid = PosixString::fromString('hello'); $invalid = PosixString::fromString('Hello'); expect($valid->isLower())->toBeTrue(); expect($invalid->isLower())->toBeFalse(); }); it('validates print (printable, including space)', function () { $valid = PosixString::fromString('Hello World!'); $invalid = PosixString::fromString("Hello\x00World"); expect($valid->isPrint())->toBeTrue(); expect($invalid->isPrint())->toBeFalse(); }); it('validates punct (punctuation)', function () { $valid = PosixString::fromString('!@#$%^&*()'); $invalid = PosixString::fromString('abc!@#'); expect($valid->isPunct())->toBeTrue(); expect($invalid->isPunct())->toBeFalse(); }); it('validates space (whitespace)', function () { $valid = PosixString::fromString(" \t\n\r"); $invalid = PosixString::fromString('abc'); expect($valid->isSpace())->toBeTrue(); expect($invalid->isSpace())->toBeFalse(); }); it('validates upper (uppercase)', function () { $valid = PosixString::fromString('HELLO'); $invalid = PosixString::fromString('Hello'); expect($valid->isUpper())->toBeTrue(); expect($invalid->isUpper())->toBeFalse(); }); it('validates xdigit (hexadecimal)', function () { $valid = PosixString::fromString('0123456789abcdefABCDEF'); $invalid = PosixString::fromString('0123xyz'); expect($valid->isXdigit())->toBeTrue(); expect($invalid->isXdigit())->toBeFalse(); }); it('validates word (alphanumeric + underscore)', function () { $valid = PosixString::fromString('user_name123'); $invalid = PosixString::fromString('user-name'); expect($valid->isWord())->toBeTrue(); expect($invalid->isWord())->toBeFalse(); }); }); describe('Helper Methods', function () { it('checks if string contains POSIX class characters', function () { $str = PosixString::fromString('hello123world'); expect($str->containsPosixClass('alpha'))->toBeTrue(); expect($str->containsPosixClass('digit'))->toBeTrue(); expect($str->containsPosixClass('punct'))->toBeFalse(); }); it('counts POSIX class characters', function () { $str = PosixString::fromString('abc123xyz789'); expect($str->countPosixClass('alpha'))->toBe(6); expect($str->countPosixClass('digit'))->toBe(6); expect($str->countPosixClass('punct'))->toBe(0); }); it('filters by POSIX class', function () { $str = PosixString::fromString('abc123xyz'); $alphaOnly = $str->filterByPosixClass('alpha'); $digitOnly = $str->filterByPosixClass('digit'); expect($alphaOnly->value)->toBe('abcxyz'); expect($digitOnly->value)->toBe('123'); }); }); describe('Conversion Methods', function () { it('converts to TypedString', function () { $posix = PosixString::fromString('test'); $typed = $posix->toTypedString(); expect($typed->value)->toBe('test'); expect($typed->isAlphabetic())->toBeTrue(); }); it('converts to string', function () { $str = PosixString::fromString('hello'); expect($str->toString())->toBe('hello'); expect((string) $str)->toBe('hello'); }); }); describe('Comparison Methods', function () { it('checks equality', function () { $str1 = PosixString::fromString('test'); $str2 = PosixString::fromString('test'); $str3 = PosixString::fromString('other'); expect($str1->equals($str2))->toBeTrue(); expect($str1->equals($str3))->toBeFalse(); }); it('checks if empty', function () { $empty = PosixString::fromString(''); $notEmpty = PosixString::fromString('test'); expect($empty->isEmpty())->toBeTrue(); expect($notEmpty->isEmpty())->toBeFalse(); }); it('checks if not empty', function () { $empty = PosixString::fromString(''); $notEmpty = PosixString::fromString('test'); expect($empty->isNotEmpty())->toBeFalse(); expect($notEmpty->isNotEmpty())->toBeTrue(); }); }); describe('Edge Cases', function () { it('handles empty string validation', function () { $empty = PosixString::fromString(''); expect($empty->isAlpha())->toBeFalse(); expect($empty->isAlnum())->toBeFalse(); expect($empty->isDigit())->toBeFalse(); }); it('handles single character validation', function () { $alpha = PosixString::fromString('a'); $digit = PosixString::fromString('5'); $punct = PosixString::fromString('!'); expect($alpha->isAlpha())->toBeTrue(); expect($digit->isDigit())->toBeTrue(); expect($punct->isPunct())->toBeTrue(); }); it('handles mixed character sets', function () { $mixed = PosixString::fromString('abc123!@#'); expect($mixed->isAlnum())->toBeFalse(); // Contains punctuation expect($mixed->containsPosixClass('alpha'))->toBeTrue(); expect($mixed->containsPosixClass('digit'))->toBeTrue(); expect($mixed->containsPosixClass('punct'))->toBeTrue(); }); }); describe('Real World Use Cases', function () { it('validates usernames', function () { $validUsername = PosixString::fromString('john_doe_123'); $invalidUsername = PosixString::fromString('john-doe@example'); expect($validUsername->isWord())->toBeTrue(); expect($invalidUsername->isWord())->toBeFalse(); }); it('validates identifiers', function () { $validId = PosixString::fromString('MAX_TIMEOUT_VALUE'); $invalidId = PosixString::fromString('max-timeout-value'); expect($validId->isWord())->toBeTrue(); expect($invalidId->isWord())->toBeFalse(); }); it('validates hexadecimal color codes', function () { $validColor = PosixString::fromString('FF5733'); $invalidColor = PosixString::fromString('GG5733'); expect($validColor->isXdigit())->toBeTrue(); expect($invalidColor->isXdigit())->toBeFalse(); }); it('validates numeric strings', function () { $validNum = PosixString::fromString('123456'); $invalidNum = PosixString::fromString('12.34'); expect($validNum->isDigit())->toBeTrue(); expect($invalidNum->isDigit())->toBeFalse(); }); }); });