value)->toBe('user_123'); }); it('can be created from string', function () { $id = EntityId::fromString('product_456'); expect($id->toString())->toBe('product_456'); }); it('can generate unique ID', function () { $id1 = EntityId::generate(); $id2 = EntityId::generate(); expect($id1->toString())->not->toBe($id2->toString()); expect($id1->toString())->toStartWith('entity_'); }); it('converts to string', function () { $id = new EntityId('test_789'); expect($id->__toString())->toBe('test_789'); }); it('compares equality correctly', function () { $id1 = new EntityId('same_id'); $id2 = new EntityId('same_id'); $id3 = new EntityId('different_id'); expect($id1->equals($id2))->toBeTrue(); expect($id1->equals($id3))->toBeFalse(); }); it('throws exception for empty ID', function () { expect(fn () => new EntityId(''))->toThrow(InvalidArgumentException::class); expect(fn () => new EntityId(' '))->toThrow(InvalidArgumentException::class); }); it('throws exception for too long ID', function () { $longId = str_repeat('a', 256); expect(fn () => new EntityId($longId))->toThrow(InvalidArgumentException::class); }); it('throws exception for invalid characters', function () { expect(fn () => new EntityId('invalid@id'))->toThrow(InvalidArgumentException::class); expect(fn () => new EntityId('invalid id'))->toThrow(InvalidArgumentException::class); expect(fn () => new EntityId('invalid/id'))->toThrow(InvalidArgumentException::class); }); it('allows valid characters', function () { expect(fn () => new EntityId('valid_id.123-test'))->not->toThrow(InvalidArgumentException::class); expect(fn () => new EntityId('123'))->not->toThrow(InvalidArgumentException::class); expect(fn () => new EntityId('a'))->not->toThrow(InvalidArgumentException::class); }); });