value)->toBe('ma-belle-gamme') ->and((string) $slug)->toBe('ma-belle-gamme'); }); test('it throws when slug is empty', function () { // GIVEN $empty = ' '; // WHEN & THEN expect(fn () => new Slug($empty)) ->toThrow(\InvalidArgumentException::class, 'Slug cannot be empty.'); }); test('it throws when slug exceeds 255 characters', function () { // GIVEN $long = str_repeat('a', 256); // WHEN & THEN expect(fn () => new Slug($long)) ->toThrow(\InvalidArgumentException::class, 'Slug cannot exceed 255 characters.'); }); test('it throws when slug format is invalid', function () { // GIVEN $invalid = 'Invalid Slug With Spaces!'; // WHEN & THEN expect(fn () => new Slug($invalid)) ->toThrow(\InvalidArgumentException::class, 'Slug format is invalid.'); }); test('it creates slug from raw string with fromString', function () { // GIVEN $raw = 'Nouvelle Gamme Spéciale 2026 !'; // WHEN $slug = Slug::fromString($raw); // THEN expect($slug->value)->toBe('nouvelle-gamme-speciale-2026') ->and((string) $slug)->toBe('nouvelle-gamme-speciale-2026'); }); test('it throws fromString when string produces empty slug', function () { // GIVEN $raw = '??? !!!'; // WHEN & THEN expect(fn () => Slug::fromString($raw)) ->toThrow(\InvalidArgumentException::class, 'Cannot generate a valid slug from given string.'); }); });