From 163411410d03d2962f1d7bab3edb8fecf6cc3b38 Mon Sep 17 00:00:00 2001 From: Raffaele Carelle Date: Fri, 11 Oct 2024 17:14:32 +0200 Subject: [PATCH 1/9] [String] Add `AbstractString::pascal()` method --- AbstractString.php | 5 +++++ CHANGELOG.md | 5 +++++ Tests/AbstractAsciiTestCase.php | 27 +++++++++++++++++++++++++++ Tests/AbstractUnicodeTestCase.php | 11 +++++++++++ 4 files changed, 48 insertions(+) diff --git a/AbstractString.php b/AbstractString.php index 500d7c3..fc60f8f 100644 --- a/AbstractString.php +++ b/AbstractString.php @@ -438,6 +438,11 @@ public function kebab(): static return $this->snake()->replace('_', '-'); } + public function pascal(): static + { + return $this->camel()->title(); + } + abstract public function splice(string $replacement, int $start = 0, ?int $length = null): static; /** diff --git a/CHANGELOG.md b/CHANGELOG.md index ff505b1..ac4b8fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +7.3 +--- + +* Add the `AbstractString::pascal()` method + 7.2 --- diff --git a/Tests/AbstractAsciiTestCase.php b/Tests/AbstractAsciiTestCase.php index ee4890f..e673f27 100644 --- a/Tests/AbstractAsciiTestCase.php +++ b/Tests/AbstractAsciiTestCase.php @@ -1118,6 +1118,33 @@ public static function provideKebab(): array ]; } + /** + * @dataProvider providePascal + */ + public function testPascal(string $expectedString, string $origin) + { + $instance = static::createFromString($origin)->pascal(); + + $this->assertEquals(static::createFromString($expectedString), $instance); + $this->assertNotSame($origin, $instance, 'Strings should be immutable'); + } + + public static function providePascal(): array + { + return [ + ['', ''], + ['XY', 'x_y'], + ['XuYo', 'xu_yo'], + ['SymfonyIsGreat', 'symfony_is_great'], + ['Symfony5IsGreat', 'symfony_5_is_great'], + ['SymfonyIsGreat', 'Symfony is great'], + ['SYMFONYISGREAT', 'SYMFONY_IS_GREAT'], + ['SymfonyIsAGreatFramework', 'Symfony is a great framework'], + ['SymfonyIsGREAT', '*Symfony* is GREAT!!'], + ['SYMFONY', 'SYMFONY'], + ]; + } + /** * @dataProvider provideStartsWith */ diff --git a/Tests/AbstractUnicodeTestCase.php b/Tests/AbstractUnicodeTestCase.php index bde19d7..2433f89 100644 --- a/Tests/AbstractUnicodeTestCase.php +++ b/Tests/AbstractUnicodeTestCase.php @@ -655,6 +655,17 @@ public static function provideCamel() ); } + public static function providePascal(): array + { + return array_merge( + parent::providePascal(), + [ + ['SymfonyIstÄußerstCool', 'symfonyIstÄußerstCool'], + ['SymfonyWithEmojis', 'Symfony with 😃 emojis'], + ] + ); + } + public static function provideSnake() { return array_merge( From 373a11f2d03e71934a0023888edf3328a583e4ec Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 5 Jan 2025 17:34:30 +0100 Subject: [PATCH 2/9] Fix typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac4b8fb..0782ae2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ CHANGELOG 7.3 --- -* Add the `AbstractString::pascal()` method + * Add the `AbstractString::pascal()` method 7.2 --- From a75110076ac661a4a52792b5a1d286d113653a70 Mon Sep 17 00:00:00 2001 From: Dariusz Ruminski Date: Fri, 21 Feb 2025 02:28:48 +0100 Subject: [PATCH 3/9] chore: PHP CS Fixer - allow header validator --- Resources/WcswidthDataGenerator.php | 7 +++++++ Resources/data/wcswidth_table_wide.php | 7 +++++++ Resources/data/wcswidth_table_zero.php | 7 +++++++ 3 files changed, 21 insertions(+) diff --git a/Resources/WcswidthDataGenerator.php b/Resources/WcswidthDataGenerator.php index 19e6e89..005b148 100644 --- a/Resources/WcswidthDataGenerator.php +++ b/Resources/WcswidthDataGenerator.php @@ -83,10 +83,17 @@ private function getHeader(string $version): string + * * This file has been auto-generated by the Symfony String Component for internal use. * * Unicode version: $version * Date: $date + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ diff --git a/Resources/data/wcswidth_table_wide.php b/Resources/data/wcswidth_table_wide.php index 6a75094..b2c94c3 100644 --- a/Resources/data/wcswidth_table_wide.php +++ b/Resources/data/wcswidth_table_wide.php @@ -1,10 +1,17 @@ + * * This file has been auto-generated by the Symfony String Component for internal use. * * Unicode version: 16.0.0 * Date: 2024-09-11T08:21:22+00:00 + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ return [ diff --git a/Resources/data/wcswidth_table_zero.php b/Resources/data/wcswidth_table_zero.php index fdd7f3c..287c36c 100644 --- a/Resources/data/wcswidth_table_zero.php +++ b/Resources/data/wcswidth_table_zero.php @@ -1,10 +1,17 @@ + * * This file has been auto-generated by the Symfony String Component for internal use. * * Unicode version: 16.0.0 * Date: 2024-09-11T08:21:22+00:00 + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ return [ From aa2ed96dc8c7dc2130b9efb6d164315646f85b35 Mon Sep 17 00:00:00 2001 From: "Phil E. Taylor" Date: Sun, 17 Aug 2025 23:52:18 +0100 Subject: [PATCH 4/9] specific fix to avoid 'outag' when inflecting 'outages' Signed-off-by: Phil E. Taylor --- Inflector/EnglishInflector.php | 3 +++ Tests/Inflector/EnglishInflectorTest.php | 1 + 2 files changed, 4 insertions(+) diff --git a/Inflector/EnglishInflector.php b/Inflector/EnglishInflector.php index 73db80c..1105c06 100644 --- a/Inflector/EnglishInflector.php +++ b/Inflector/EnglishInflector.php @@ -166,6 +166,9 @@ final class EnglishInflector implements InflectorInterface // edges (edge) ['segd', 4, true, true, 'dge'], + // outages (outage) - specific fix to avoid 'outag' + ['segatuo', 7, true, true, 'outage'], + // roses (rose), garages (garage), cassettes (cassette), // waltzes (waltz), heroes (hero), bushes (bush), arches (arch), // shoes (shoe) diff --git a/Tests/Inflector/EnglishInflectorTest.php b/Tests/Inflector/EnglishInflectorTest.php index 16287f4..243242f 100644 --- a/Tests/Inflector/EnglishInflectorTest.php +++ b/Tests/Inflector/EnglishInflectorTest.php @@ -124,6 +124,7 @@ public static function singularizeProvider() ['news', 'news'], ['oases', ['oas', 'oase', 'oasis']], ['objectives', 'objective'], + ['outages', 'outage'], ['oxen', 'ox'], ['parties', 'party'], ['people', 'person'], From ae3ce5e4883b11eccf399f3f679cf1048f9243b6 Mon Sep 17 00:00:00 2001 From: Ruud Kamphuis Date: Tue, 19 Aug 2025 19:06:06 +0200 Subject: [PATCH 5/9] [String] Fix issues singular Before it would suggest issu and issues. It should only be issues. --- Inflector/EnglishInflector.php | 3 +++ Tests/Inflector/EnglishInflectorTest.php | 2 ++ 2 files changed, 5 insertions(+) diff --git a/Inflector/EnglishInflector.php b/Inflector/EnglishInflector.php index 1105c06..7224b47 100644 --- a/Inflector/EnglishInflector.php +++ b/Inflector/EnglishInflector.php @@ -28,6 +28,9 @@ final class EnglishInflector implements InflectorInterface // bacteria (bacterium) ['airetcab', 8, true, true, 'bacterium'], + // issues (issue) + ['seussi', 6, true, true, 'issue'], + // corpora (corpus) ['aroproc', 7, true, true, 'corpus'], diff --git a/Tests/Inflector/EnglishInflectorTest.php b/Tests/Inflector/EnglishInflectorTest.php index 243242f..789a73d 100644 --- a/Tests/Inflector/EnglishInflectorTest.php +++ b/Tests/Inflector/EnglishInflectorTest.php @@ -103,6 +103,7 @@ public static function singularizeProvider() ['indices', ['index', 'indix', 'indice']], ['ions', 'ion'], ['irises', ['iris', 'irise', 'irisis']], + ['issues', 'issue'], ['kisses', 'kiss'], ['knives', 'knife'], ['lamps', 'lamp'], @@ -262,6 +263,7 @@ public static function pluralizeProvider() ['index', ['indicies', 'indexes']], ['ion', 'ions'], ['iris', 'irises'], + ['issue', 'issues'], ['kiss', 'kisses'], ['knife', 'knives'], ['lamp', 'lamps'], From 7cdec7edfaf2cdd9c18901e35bcf9653d6209ff1 Mon Sep 17 00:00:00 2001 From: Ruud Kamphuis Date: Fri, 22 Aug 2025 14:33:20 +0200 Subject: [PATCH 6/9] [String] Fix nodes singular Before it would suggest nod. It should be node. --- Inflector/EnglishInflector.php | 6 ++++++ Tests/Inflector/EnglishInflectorTest.php | 2 ++ 2 files changed, 8 insertions(+) diff --git a/Inflector/EnglishInflector.php b/Inflector/EnglishInflector.php index 7224b47..b9d74c0 100644 --- a/Inflector/EnglishInflector.php +++ b/Inflector/EnglishInflector.php @@ -25,6 +25,9 @@ final class EnglishInflector implements InflectorInterface // Fourth entry: Whether the suffix may succeed a consonant // Fifth entry: singular suffix, normal + // nodes (node) + ['sedon', 5, true, true, 'node'], + // bacteria (bacterium) ['airetcab', 8, true, true, 'bacterium'], @@ -202,6 +205,9 @@ final class EnglishInflector implements InflectorInterface // Fourth entry: Whether the suffix may succeed a consonant // Fifth entry: plural suffix, normal + // nodes (node) + ['edon', 4, true, true, 'nodes'], + // axes (axis) ['sixa', 4, false, false, 'axes'], diff --git a/Tests/Inflector/EnglishInflectorTest.php b/Tests/Inflector/EnglishInflectorTest.php index 789a73d..e3b35cb 100644 --- a/Tests/Inflector/EnglishInflectorTest.php +++ b/Tests/Inflector/EnglishInflectorTest.php @@ -123,6 +123,7 @@ public static function singularizeProvider() ['nebulae', 'nebula'], ['neuroses', ['neuros', 'neurose', 'neurosis']], ['news', 'news'], + ['nodes', 'node'], ['oases', ['oas', 'oase', 'oasis']], ['objectives', 'objective'], ['outages', 'outage'], @@ -281,6 +282,7 @@ public static function pluralizeProvider() ['nebula', 'nebulae'], ['neurosis', 'neuroses'], ['news', 'news'], + ['node', 'nodes'], ['oasis', 'oases'], ['objective', 'objectives'], ['ox', 'oxen'], From 145849416ed3ffcb7b6ea1617c9efb48677b13d7 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Mon, 1 Sep 2025 07:53:39 +0200 Subject: [PATCH 7/9] [String][Inflector] Fix edge cases Fixed both singularization and pluralization for: - passersby <-> passerby (compound word) - insignia/insignias <-> insigne (Latin singular) - rattles <-> rattle (already worked, added test coverage) --- Inflector/EnglishInflector.php | 13 +++++++++++++ Tests/Inflector/EnglishInflectorTest.php | 12 +++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/Inflector/EnglishInflector.php b/Inflector/EnglishInflector.php index b9d74c0..5583669 100644 --- a/Inflector/EnglishInflector.php +++ b/Inflector/EnglishInflector.php @@ -25,6 +25,13 @@ final class EnglishInflector implements InflectorInterface // Fourth entry: Whether the suffix may succeed a consonant // Fifth entry: singular suffix, normal + // insignias (insigne), insignia (insigne) + ['saingisni', 9, true, true, 'insigne'], + ['aingisni', 8, true, true, 'insigne'], + + // passersby (passerby) + ['ybsressap', 9, true, true, 'passerby'], + // nodes (node) ['sedon', 5, true, true, 'node'], @@ -205,6 +212,12 @@ final class EnglishInflector implements InflectorInterface // Fourth entry: Whether the suffix may succeed a consonant // Fifth entry: plural suffix, normal + // passerby (passersby) + ['ybressap', 8, true, true, 'passersby'], + + // insigne (insignia, insignias) + ['engisni', 7, true, true, ['insignia', 'insignias']], + // nodes (node) ['edon', 4, true, true, 'nodes'], diff --git a/Tests/Inflector/EnglishInflectorTest.php b/Tests/Inflector/EnglishInflectorTest.php index e3b35cb..aeff309 100644 --- a/Tests/Inflector/EnglishInflectorTest.php +++ b/Tests/Inflector/EnglishInflectorTest.php @@ -171,16 +171,15 @@ public static function singularizeProvider() ['waltzes', ['waltz', 'waltze']], ['wives', 'wife'], ['zombies', 'zombie'], + ['passersby', 'passerby'], + ['rattles', 'rattle'], + ['insignia', 'insigne'], + ['insignias', 'insigne'], // test casing: if the first letter was uppercase, it should remain so ['Men', 'Man'], ['GrandChildren', 'GrandChild'], ['SubTrees', 'SubTree'], - - // Known issues - // ['insignia', 'insigne'], - // ['insignias', 'insigne'], - // ['rattles', 'rattle'], ]; } @@ -262,6 +261,7 @@ public static function pluralizeProvider() ['house', 'houses'], ['icon', 'icons'], ['index', ['indicies', 'indexes']], + ['insigne', ['insignia', 'insignias']], ['ion', 'ions'], ['iris', 'irises'], ['issue', 'issues'], @@ -287,6 +287,7 @@ public static function pluralizeProvider() ['objective', 'objectives'], ['ox', 'oxen'], ['party', 'parties'], + ['passerby', 'passersby'], ['person', ['persons', 'people']], ['phenomenon', 'phenomena'], ['photo', 'photos'], @@ -298,6 +299,7 @@ public static function pluralizeProvider() ['quiz', 'quizzes'], ['quorum', ['quora', 'quorums']], ['radius', 'radii'], + ['rattle', 'rattles'], ['roof', ['roofs', 'rooves']], ['rose', 'roses'], ['sandwich', 'sandwiches'], From 2cc50899684cb3caccbd82140a9221a7456679b4 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 5 Sep 2025 14:17:45 +0200 Subject: [PATCH 8/9] use the empty string instead of null as an array offset --- Slugger/AsciiSlugger.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Slugger/AsciiSlugger.php b/Slugger/AsciiSlugger.php index d0c3386..d4d4e94 100644 --- a/Slugger/AsciiSlugger.php +++ b/Slugger/AsciiSlugger.php @@ -131,8 +131,8 @@ public function slug(string $string, string $separator = '-', ?string $locale = if (\is_array($this->symbolsMap)) { $map = null; - if (isset($this->symbolsMap[$locale])) { - $map = $this->symbolsMap[$locale]; + if (isset($this->symbolsMap[$locale ?? ''])) { + $map = $this->symbolsMap[$locale ?? '']; } else { $parent = self::getParentLocale($locale); if ($parent && isset($this->symbolsMap[$parent])) { From 5621f039a71a11c87c106c1c598bdcd04a19aeea Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 11 Sep 2025 16:32:46 +0200 Subject: [PATCH 9/9] [PhpUnitBridge] Fix gathering deprecation in phpt --- Tests/LazyStringTest.php | 3 --- composer.json | 3 +-- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/Tests/LazyStringTest.php b/Tests/LazyStringTest.php index b5405bb..cb52644 100644 --- a/Tests/LazyStringTest.php +++ b/Tests/LazyStringTest.php @@ -12,7 +12,6 @@ namespace Symfony\Component\String\Tests; use PHPUnit\Framework\TestCase; -use Symfony\Component\ErrorHandler\ErrorHandler; use Symfony\Component\String\LazyString; class LazyStringTest extends TestCase @@ -34,8 +33,6 @@ public function testLazyString() */ public function testReturnTypeError() { - ErrorHandler::register(); - $s = LazyString::fromCallable(fn () => []); $this->expectException(\TypeError::class); diff --git a/composer.json b/composer.json index 56c1368..1a2b41e 100644 --- a/composer.json +++ b/composer.json @@ -23,9 +23,8 @@ "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { - "symfony/error-handler": "^5.4|^6.0|^7.0", - "symfony/intl": "^6.2|^7.0", "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/intl": "^6.2|^7.0", "symfony/translation-contracts": "^2.5|^3.0", "symfony/var-exporter": "^5.4|^6.0|^7.0" },