From 28d58a7e2471ae40b0fe02563a46dea6eafd99ee Mon Sep 17 00:00:00 2001 From: seb-jean Date: Sat, 24 Dec 2022 09:05:02 +0100 Subject: [PATCH] Add support for kebab case --- .../Component/String/AbstractString.php | 2 ++ .../String/AbstractUnicodeString.php | 8 ++++++ src/Symfony/Component/String/ByteString.php | 8 ++++++ .../String/Tests/AbstractAsciiTestCase.php | 28 +++++++++++++++++++ .../String/Tests/AbstractUnicodeTestCase.php | 10 +++++++ 5 files changed, 56 insertions(+) diff --git a/src/Symfony/Component/String/AbstractString.php b/src/Symfony/Component/String/AbstractString.php index bf491f88d61fe..442e06a5811bf 100644 --- a/src/Symfony/Component/String/AbstractString.php +++ b/src/Symfony/Component/String/AbstractString.php @@ -390,6 +390,8 @@ public function jsonSerialize(): string return $this->string; } + abstract public function kebab(): static; + abstract public function length(): int; abstract public function lower(): static; diff --git a/src/Symfony/Component/String/AbstractUnicodeString.php b/src/Symfony/Component/String/AbstractUnicodeString.php index 52912276f174f..033f38edd069a 100644 --- a/src/Symfony/Component/String/AbstractUnicodeString.php +++ b/src/Symfony/Component/String/AbstractUnicodeString.php @@ -214,6 +214,14 @@ public function join(array $strings, string $lastGlue = null): static return $str; } + public function kebab(): static + { + $str = $this->camel(); + $str->string = mb_strtolower(preg_replace(['/(\p{Lu}+)(\p{Lu}\p{Ll})/u', '/([\p{Ll}0-9])(\p{Lu})/u'], '\1-\2', $str->string), 'UTF-8'); + + return $str; + } + public function lower(): static { $str = clone $this; diff --git a/src/Symfony/Component/String/ByteString.php b/src/Symfony/Component/String/ByteString.php index 212290fed97a0..1635e14a0f2ef 100644 --- a/src/Symfony/Component/String/ByteString.php +++ b/src/Symfony/Component/String/ByteString.php @@ -215,6 +215,14 @@ public function join(array $strings, string $lastGlue = null): static return $str; } + public function kebab(): static + { + $str = $this->camel(); + $str->string = strtolower(preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'], '\1-\2', $str->string)); + + return $str; + } + public function length(): int { return \strlen($this->string); diff --git a/src/Symfony/Component/String/Tests/AbstractAsciiTestCase.php b/src/Symfony/Component/String/Tests/AbstractAsciiTestCase.php index a0cf2068f9476..19fd78524ea5d 100644 --- a/src/Symfony/Component/String/Tests/AbstractAsciiTestCase.php +++ b/src/Symfony/Component/String/Tests/AbstractAsciiTestCase.php @@ -1080,6 +1080,34 @@ public static function provideSnake() ]; } + /** + * @dataProvider provideKebab + */ + public function testKebab(string $expectedString, string $origin) + { + $instance = static::createFromString($origin)->kebab(); + + $this->assertEquals(static::createFromString($expectedString), $instance); + } + + public static function provideKebab() + { + return [ + ['', ''], + ['x-y', 'x_y'], + ['x-y', 'X_Y'], + ['xu-yo', 'xu_yo'], + ['symfony-is-great', 'symfonyIsGreat'], + ['symfony5-is-great', 'symfony5IsGreat'], + ['symfony5is-great', 'symfony5isGreat'], + ['symfony-is-great', 'Symfony is great'], + ['symfony-is-a-great-framework', 'symfonyIsAGreatFramework'], + ['symfony-is-great', 'symfonyIsGREAT'], + ['symfony-is-really-great', 'symfonyIsREALLYGreat'], + ['symfony', 'SYMFONY'], + ]; + } + /** * @dataProvider provideStartsWith */ diff --git a/src/Symfony/Component/String/Tests/AbstractUnicodeTestCase.php b/src/Symfony/Component/String/Tests/AbstractUnicodeTestCase.php index d8f71ffd93d6a..5586195458bd1 100644 --- a/src/Symfony/Component/String/Tests/AbstractUnicodeTestCase.php +++ b/src/Symfony/Component/String/Tests/AbstractUnicodeTestCase.php @@ -546,6 +546,16 @@ public static function provideSnake() ); } + public static function provideKebab() + { + return array_merge( + parent::provideKebab(), + [ + ['symfony-ist-äußerst-cool', 'symfonyIstÄußerstCool'], + ] + ); + } + public static function provideEqualsTo() { return array_merge(