diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 35eb7c6c53d..1b6ae3e5fa9 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -30,7 +30,8 @@ return (new PhpCsFixer\Config()) ->setParallelConfig(PhpCsFixer\Runner\Parallel\ParallelConfigFactory::detect()) ->setRules([ - '@PHPUnit75Migration:risky' => true, + '@PHP81Migration' => true, // take lowest version from `git grep -h '"php"' **/composer.json | uniq | sort` + '@PHPUnit91Migration:risky' => true, '@Symfony' => true, '@Symfony:risky' => true, 'protected_to_private' => false, diff --git a/src/Autocomplete/src/Maker/MakeAutocompleteField.php b/src/Autocomplete/src/Maker/MakeAutocompleteField.php index 1588b2cb22c..9bbdcba43d8 100644 --- a/src/Autocomplete/src/Maker/MakeAutocompleteField.php +++ b/src/Autocomplete/src/Maker/MakeAutocompleteField.php @@ -57,12 +57,12 @@ public function configureCommand(Command $command, InputConfiguration $inputConf { $command ->setHelp(<<%command.name% command generates an Ajax-autocomplete form field class for symfony/ux-autocomplete + The %command.name% command generates an Ajax-autocomplete form field class for symfony/ux-autocomplete -php %command.full_name% + php %command.full_name% -The command will ask you which entity the field is for and what to call your new class. -EOF) + The command will ask you which entity the field is for and what to call your new class. + EOF) ; } diff --git a/src/Chartjs/tests/Kernel/TwigAppKernel.php b/src/Chartjs/tests/Kernel/TwigAppKernel.php index 76de3dbd28c..9b69148ad8e 100644 --- a/src/Chartjs/tests/Kernel/TwigAppKernel.php +++ b/src/Chartjs/tests/Kernel/TwigAppKernel.php @@ -57,7 +57,7 @@ private function createTmpDir(string $type): string $dir = sys_get_temp_dir().'/chartjs_bundle/'.uniqid($type.'_', true); if (!file_exists($dir)) { - mkdir($dir, 0777, true); + mkdir($dir, 0o777, true); } return $dir; diff --git a/src/Cropperjs/tests/Kernel/AppKernelTrait.php b/src/Cropperjs/tests/Kernel/AppKernelTrait.php index e0903a2f98a..5f0f0c2a40f 100644 --- a/src/Cropperjs/tests/Kernel/AppKernelTrait.php +++ b/src/Cropperjs/tests/Kernel/AppKernelTrait.php @@ -33,7 +33,7 @@ private function createTmpDir(string $type): string $dir = sys_get_temp_dir().'/cropperjs_bundle/'.uniqid($type.'_', true); if (!file_exists($dir)) { - mkdir($dir, 0777, true); + mkdir($dir, 0o777, true); } return $dir; diff --git a/src/Dropzone/tests/Kernel/AppKernelTrait.php b/src/Dropzone/tests/Kernel/AppKernelTrait.php index 742980b54bb..795b0d25a16 100644 --- a/src/Dropzone/tests/Kernel/AppKernelTrait.php +++ b/src/Dropzone/tests/Kernel/AppKernelTrait.php @@ -33,7 +33,7 @@ private function createTmpDir(string $type): string $dir = sys_get_temp_dir().'/dropzone_bundle/'.uniqid($type.'_', true); if (!file_exists($dir)) { - mkdir($dir, 0777, true); + mkdir($dir, 0o777, true); } return $dir; diff --git a/src/Icons/src/Command/SearchIconCommand.php b/src/Icons/src/Command/SearchIconCommand.php index f3ded32fd14..63ba817f13d 100644 --- a/src/Icons/src/Command/SearchIconCommand.php +++ b/src/Icons/src/Command/SearchIconCommand.php @@ -51,18 +51,18 @@ protected function configure(): void ->addArgument('name', InputArgument::OPTIONAL, 'Name of the icon (leave empty to search for sets)') ->setHelp( <<%command.name% command search icon sets and icons from ux.symfony.com + The %command.name% command search icon sets and icons from ux.symfony.com -To search for icon sets, pass the prefix or name of the icon set (or a part of it): + To search for icon sets, pass the prefix or name of the icon set (or a part of it): - php %command.full_name% bootstrap - php %command.full_name% material + php %command.full_name% bootstrap + php %command.full_name% material -To search for icons, pass the prefix of the icon set and the name of the icon: + To search for icons, pass the prefix of the icon set and the name of the icon: - php %command.full_name% bootstrap star + php %command.full_name% bootstrap star -EOF + EOF ); } diff --git a/src/Icons/tests/Integration/RenderIconsInTwigTest.php b/src/Icons/tests/Integration/RenderIconsInTwigTest.php index ad189bb9fbe..caca365c500 100644 --- a/src/Icons/tests/Integration/RenderIconsInTwigTest.php +++ b/src/Icons/tests/Integration/RenderIconsInTwigTest.php @@ -25,18 +25,18 @@ public function testRenderIcons() $this->assertSame( << -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • - - HTML, + + HTML, trim($output) ); } diff --git a/src/LazyImage/tests/BlurHash/BlurHashTest.php b/src/LazyImage/tests/BlurHash/BlurHashTest.php index a5b6fcfc500..11b87a2cdbb 100644 --- a/src/LazyImage/tests/BlurHash/BlurHashTest.php +++ b/src/LazyImage/tests/BlurHash/BlurHashTest.php @@ -216,14 +216,14 @@ public function testTwigExtension() if (BlurHash::intervention3()) { $expected = <<assertSame($expected, $output); diff --git a/src/LazyImage/tests/Kernel/AppKernelTrait.php b/src/LazyImage/tests/Kernel/AppKernelTrait.php index b5cc57be42a..37a70f1e650 100644 --- a/src/LazyImage/tests/Kernel/AppKernelTrait.php +++ b/src/LazyImage/tests/Kernel/AppKernelTrait.php @@ -33,7 +33,7 @@ private function createTmpDir(string $type): string $dir = sys_get_temp_dir().'/lazyimage_bundle/'.uniqid($type.'_', true); if (!file_exists($dir)) { - mkdir($dir, 0777, true); + mkdir($dir, 0o777, true); } return $dir; diff --git a/src/Map/tests/Kernel/AppKernelTrait.php b/src/Map/tests/Kernel/AppKernelTrait.php index 593759b5f12..7a760a9267b 100644 --- a/src/Map/tests/Kernel/AppKernelTrait.php +++ b/src/Map/tests/Kernel/AppKernelTrait.php @@ -33,7 +33,7 @@ private function createTmpDir(string $type): string $dir = sys_get_temp_dir().'/map_bundle/'.uniqid($type.'_', true); if (!file_exists($dir)) { - mkdir($dir, 0777, true); + mkdir($dir, 0o777, true); } return $dir; diff --git a/src/Notify/tests/Kernel/TwigAppKernel.php b/src/Notify/tests/Kernel/TwigAppKernel.php index 59910fd30eb..8778cd86b76 100644 --- a/src/Notify/tests/Kernel/TwigAppKernel.php +++ b/src/Notify/tests/Kernel/TwigAppKernel.php @@ -73,7 +73,7 @@ private function createTmpDir(string $type): string $dir = sys_get_temp_dir().'/notify_bundle/'.uniqid($type.'_', true); if (!file_exists($dir)) { - mkdir($dir, 0777, true); + mkdir($dir, 0o777, true); } return $dir; diff --git a/src/React/src/AssetMapper/ReactControllerLoaderAssetCompiler.php b/src/React/src/AssetMapper/ReactControllerLoaderAssetCompiler.php index 637979b7769..3bb7ed704fb 100644 --- a/src/React/src/AssetMapper/ReactControllerLoaderAssetCompiler.php +++ b/src/React/src/AssetMapper/ReactControllerLoaderAssetCompiler.php @@ -64,9 +64,9 @@ public function compile(string $content, MappedAsset $asset, AssetMapperInterfac $componentsJson = \sprintf('{%s}', implode(', ', $componentParts)); return <<isDebug ? 'true' : 'false'; return <<filesystem->dumpFile( 'Button/templates/components/Button.html.twig', << - {%- block content %}{% endblock -%} - -TWIG + {% props type = 'button', variant = 'default' %} + {%- set style = html_cva( + base: 'inline-flex items-center', + variants: { + variant: { + default: "bg-primary text-primary-foreground hover:bg-primary/90", + secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80", + }, + }, + ) -%} + + + TWIG ); $this->filesystem->dumpFile('Button/manifest.json', json_encode([ diff --git a/src/Toolkit/src/Command/DebugKitCommand.php b/src/Toolkit/src/Command/DebugKitCommand.php index 423403bfd95..9d472271943 100644 --- a/src/Toolkit/src/Command/DebugKitCommand.php +++ b/src/Toolkit/src/Command/DebugKitCommand.php @@ -47,13 +47,13 @@ protected function configure(): void ->addArgument('kit-path', InputArgument::OPTIONAL, 'The path to the kit to debug', '.') ->setHelp( <<<'EOF' -To debug a Kit in the current directory: - php %command.full_name% + To debug a Kit in the current directory: + php %command.full_name% -Or in another directory: - php %command.full_name% ./kits/shadcn - php %command.full_name% /path/to/my-kit -EOF + Or in another directory: + php %command.full_name% ./kits/shadcn + php %command.full_name% /path/to/my-kit + EOF ); } diff --git a/src/Toolkit/src/Command/InstallCommand.php b/src/Toolkit/src/Command/InstallCommand.php index 5fd88dde172..d9e4f65af58 100644 --- a/src/Toolkit/src/Command/InstallCommand.php +++ b/src/Toolkit/src/Command/InstallCommand.php @@ -63,18 +63,18 @@ protected function configure(): void ->addOption('force', 'f', InputOption::VALUE_NONE, 'Force the recipe installation, even if the files already exists') ->setHelp( <<%command.name% command will install a new UX Recipe in your project. + The %command.name% command will install a new UX Recipe in your project. -To install a recipe, use: + To install a recipe, use: -php %command.full_name% Button + php %command.full_name% Button -To install a recipe from a specific Kit (either official or external), use the --kit option: + To install a recipe from a specific Kit (either official or external), use the --kit option: -php %command.full_name% Button --kit=shadcn -php %command.full_name% Button --kit=https://github.com/user/my-kit -php %command.full_name% Button --kit=https://github.com/user/my-kit:branch -EOF + php %command.full_name% Button --kit=shadcn + php %command.full_name% Button --kit=https://github.com/user/my-kit + php %command.full_name% Button --kit=https://github.com/user/my-kit:branch + EOF ); } diff --git a/src/Toolkit/tests/Command/CreateKitCommandTest.php b/src/Toolkit/tests/Command/CreateKitCommandTest.php index 7f0bf75d2ca..2041cb293d6 100644 --- a/src/Toolkit/tests/Command/CreateKitCommandTest.php +++ b/src/Toolkit/tests/Command/CreateKitCommandTest.php @@ -56,62 +56,62 @@ public function testShouldBeAbleToCreateAKit() $this->assertStringEqualsFile( $this->tmpDir.'/manifest.json', <<<'JSON' - { - "$schema": "../vendor/symfony/ux-toolkit/schema-kit-v1.json", - "name": "MyKit", - "description": "A custom kit for Symfony UX Toolkit.", - "homepage": "http://example.com", - "license": "MIT" - } - JSON + { + "$schema": "../vendor/symfony/ux-toolkit/schema-kit-v1.json", + "name": "MyKit", + "description": "A custom kit for Symfony UX Toolkit.", + "homepage": "http://example.com", + "license": "MIT" + } + JSON ); $this->assertStringEqualsFile( $this->tmpDir.'/Button/manifest.json', <<<'JSON' - { - "$schema": "../vendor/symfony/ux-toolkit/schema-kit-recipe-v1.json", - "name": "Button", - "description": "A clickable element that triggers actions or events, supporting various styles and states.", - "copy-files": { - "templates/": "templates/" - }, - "dependencies": [ - { - "type": "php", - "package": "twig/extra-bundle" + { + "$schema": "../vendor/symfony/ux-toolkit/schema-kit-recipe-v1.json", + "name": "Button", + "description": "A clickable element that triggers actions or events, supporting various styles and states.", + "copy-files": { + "templates/": "templates/" }, - { - "type": "php", - "package": "twig/html-extra:^3.12.0" - }, - { - "type": "php", - "package": "tales-from-a-dev/twig-tailwind-extra" - } - ] - } - JSON + "dependencies": [ + { + "type": "php", + "package": "twig/extra-bundle" + }, + { + "type": "php", + "package": "twig/html-extra:^3.12.0" + }, + { + "type": "php", + "package": "tales-from-a-dev/twig-tailwind-extra" + } + ] + } + JSON ); $this->assertStringEqualsFile( $this->tmpDir.'/Button/templates/components/Button.html.twig', <<<'TWIG' - {% props type = 'button', variant = 'default' %} - {%- set style = html_cva( - base: 'inline-flex items-center', - variants: { - variant: { - default: "bg-primary text-primary-foreground hover:bg-primary/90", - secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80", + {% props type = 'button', variant = 'default' %} + {%- set style = html_cva( + base: 'inline-flex items-center', + variants: { + variant: { + default: "bg-primary text-primary-foreground hover:bg-primary/90", + secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80", + }, }, - }, - ) -%} + ) -%} - - TWIG + + TWIG ); } } diff --git a/src/Toolkit/tests/Functional/ComponentsRenderingTest.php b/src/Toolkit/tests/Functional/ComponentsRenderingTest.php index 7c43cb204e2..914fe5e1921 100644 --- a/src/Toolkit/tests/Functional/ComponentsRenderingTest.php +++ b/src/Toolkit/tests/Functional/ComponentsRenderingTest.php @@ -81,15 +81,15 @@ private function assertCodeRenderedMatchesHtmlSnapshot(Kit $kit, Recipe $recipe, { $info = \sprintf( << - HTML, + + HTML, $kit->manifest->name, $recipe->manifest->name, trim($code) diff --git a/src/Toolkit/tests/Kit/KitManifestTest.php b/src/Toolkit/tests/Kit/KitManifestTest.php index 97c1697089e..d3625781637 100644 --- a/src/Toolkit/tests/Kit/KitManifestTest.php +++ b/src/Toolkit/tests/Kit/KitManifestTest.php @@ -40,10 +40,10 @@ public function testFromJsonWithMissingDescription() $this->expectExceptionMessage('Property "description" is required.'); KitManifest::fromJson(<<expectExceptionMessage('Property "license" is required.'); KitManifest::fromJson(<<expectExceptionMessage('Property "homepage" is required.'); KitManifest::fromJson(<<expectExceptionMessage('Invalid homepage URL "not-a-url".'); KitManifest::fromJson(<<assertSame('kit', $manifest->name); $this->assertSame('A kit', $manifest->description); diff --git a/src/Toolkit/tests/Recipe/RecipeManifestTest.php b/src/Toolkit/tests/Recipe/RecipeManifestTest.php index dc56e109568..8f7e6a42bb1 100644 --- a/src/Toolkit/tests/Recipe/RecipeManifestTest.php +++ b/src/Toolkit/tests/Recipe/RecipeManifestTest.php @@ -44,10 +44,10 @@ public function testFromJsonWithInvalidType() $this->expectExceptionMessage('The recipe type "test" is not supported.'); RecipeManifest::fromJson(<<expectExceptionMessage('Property "name" is required.'); RecipeManifest::fromJson(<<expectExceptionMessage('Property "description" is required.'); RecipeManifest::fromJson(<<expectExceptionMessage('Property "copy-files" is required.'); RecipeManifest::fromJson(<<expectExceptionMessage('Each dependency must be an associative array.'); RecipeManifest::fromJson(<<expectExceptionMessage('The dependency type is missing for dependency #0, add "type" key.'); RecipeManifest::fromJson(<<expectExceptionMessage('The package name is missing for dependency #0, add "package" key.'); RecipeManifest::fromJson(<<expectExceptionMessage('The recipe name is missing for dependency #0, add "name" key.'); RecipeManifest::fromJson(<<assertSame(RecipeType::Component, $manifest->type); $this->assertSame('MyComponent', $manifest->name); @@ -190,25 +190,25 @@ public function testFromJsonWithMinimumValidData() public function testFromJsonWithValidData() { $manifest = RecipeManifest::fromJson(<<assertSame(RecipeType::Component, $manifest->type); $this->assertSame('MyComponent', $manifest->name); diff --git a/src/Translator/src/TranslationsDumper.php b/src/Translator/src/TranslationsDumper.php index 5ffa0fe43ba..811a0c00fdf 100644 --- a/src/Translator/src/TranslationsDumper.php +++ b/src/Translator/src/TranslationsDumper.php @@ -81,10 +81,10 @@ public function dump(MessageCatalogueInterface ...$catalogues): void json_encode($this->getLocaleFallbacks(...$catalogues), \JSON_THROW_ON_ERROR) )); $this->filesystem->dumpFile($this->dumpDir.'/configuration.d.ts', <<<'TS' -import { LocaleType } from '@symfony/ux-translator'; + import { LocaleType } from '@symfony/ux-translator'; -export declare const localeFallbacks: Record; -TS + export declare const localeFallbacks: Record; + TS ); } diff --git a/src/Translator/tests/Functional/DumpEnabledLocalesTest.php b/src/Translator/tests/Functional/DumpEnabledLocalesTest.php index 79d7f3b0edb..0083468af25 100644 --- a/src/Translator/tests/Functional/DumpEnabledLocalesTest.php +++ b/src/Translator/tests/Functional/DumpEnabledLocalesTest.php @@ -36,33 +36,33 @@ public function testShouldDumpOnlyEnabledLocales() self::assertStringEqualsFile( $translationsDumpDir.'/index.js', <<; + export declare const SYMFONY_UX_GREAT: Message<{ 'messages': { parameters: NoParametersType } }, 'en'|'fr'>; - TYPESCRIPT + TYPESCRIPT ); self::assertStringEqualsFile( $translationsDumpDir.'/configuration.js', <<; - TYPESCRIPT + export declare const localeFallbacks: Record; + TYPESCRIPT ); } } diff --git a/src/Translator/tests/Intl/IntlMessageParserTest.php b/src/Translator/tests/Intl/IntlMessageParserTest.php index d445d6d659c..cd731fbf038 100644 --- a/src/Translator/tests/Intl/IntlMessageParserTest.php +++ b/src/Translator/tests/Intl/IntlMessageParserTest.php @@ -129,12 +129,12 @@ public static function provideParse() yield 'plural' => [ <<<'EOT' -You have {itemCount, plural, - =0 {no items} - one {1 item} - other {{itemCount} items} -}. -EOT, + You have {itemCount, plural, + =0 {no items} + one {1 item} + other {{itemCount} items} + }. + EOT, [ 'val' => [ [ @@ -198,24 +198,24 @@ public static function provideParse() yield 'many parameters, plural, select, with HTML' => [ <<<'EOT' -I have {count, plural, - one{a { - gender, select, - male{male} - female{female} - other{male} - } dog - } - other{many dogs}} and {count, plural, - one{a { - gender, select, - male{male} - female{female} - other{male} - } cat - } - other{many cats}} -EOT, + I have {count, plural, + one{a { + gender, select, + male{male} + female{female} + other{male} + } dog + } + other{many dogs}} and {count, plural, + one{a { + gender, select, + male{male} + female{female} + other{male} + } cat + } + other{many cats}} + EOT, [ 'val' => [ [ diff --git a/src/Translator/tests/Kernel/AppKernelTrait.php b/src/Translator/tests/Kernel/AppKernelTrait.php index 36c6b158390..720856f7edb 100644 --- a/src/Translator/tests/Kernel/AppKernelTrait.php +++ b/src/Translator/tests/Kernel/AppKernelTrait.php @@ -33,7 +33,7 @@ private function createTmpDir(string $type): string $dir = sys_get_temp_dir().'/translator_bundle/'.uniqid($type.'_', true); if (!file_exists($dir)) { - mkdir($dir, 0777, true); + mkdir($dir, 0o777, true); } return $dir; diff --git a/src/Translator/tests/MessageParameters/Extractor/IntlMessageParametersExtractorTest.php b/src/Translator/tests/MessageParameters/Extractor/IntlMessageParametersExtractorTest.php index 5fbf12cda80..f69a8fb89d5 100644 --- a/src/Translator/tests/MessageParameters/Extractor/IntlMessageParametersExtractorTest.php +++ b/src/Translator/tests/MessageParameters/Extractor/IntlMessageParametersExtractorTest.php @@ -68,12 +68,12 @@ public static function provideExtract() yield [ << ['type' => 'string', 'values' => ['male', 'female', 'other']], ], @@ -81,11 +81,11 @@ public static function provideExtract() yield [ << ['type' => 'string', 'values' => ['yes', 'other']], 'taxRate' => ['type' => 'number'], @@ -94,27 +94,27 @@ public static function provideExtract() yield [ << ['type' => 'string', 'values' => ['female', 'male', 'other']], 'num_guests' => ['type' => 'number'], diff --git a/src/Translator/tests/TranslationsDumperTest.php b/src/Translator/tests/TranslationsDumperTest.php index f298db46ba2..679635a8b63 100644 --- a/src/Translator/tests/TranslationsDumperTest.php +++ b/src/Translator/tests/TranslationsDumperTest.php @@ -53,56 +53,56 @@ public function testDump() $this->assertFileExists(self::$translationsDumpDir.'/index.d.ts'); $this->assertStringEqualsFile(self::$translationsDumpDir.'/index.js', <<<'JAVASCRIPT' -export const NOTIFICATION_COMMENT_CREATED = {"id":"notification.comment_created","translations":{"messages+intl-icu":{"en":"Your post received a comment!","fr":"Votre article a re\u00e7u un commentaire !"}}}; -export const NOTIFICATION_COMMENT_CREATED_DESCRIPTION = {"id":"notification.comment_created.description","translations":{"messages+intl-icu":{"en":"Your post \"{title}\" has received a new comment. You can read the comment by following this link<\/a>","fr":"Votre article \"{title}\" a re\u00e7u un nouveau commentaire. Vous pouvez lire le commentaire en suivant ce lien<\/a>"}}}; -export const POST_NUM_COMMENTS = {"id":"post.num_comments","translations":{"messages+intl-icu":{"en":"{count, plural, one {# comment} other {# comments}}","fr":"{count, plural, one {# commentaire} other {# commentaires}}"},"foobar":{"en":"There is 1 comment|There are %count% comments","fr":"Il y a 1 comment|Il y a %count% comments"}}}; -export const POST_NUM_COMMENTS_1 = {"id":"post.num_comments.","translations":{"messages+intl-icu":{"en":"{count, plural, one {# comment} other {# comments}} (should not conflict with the previous one.)","fr":"{count, plural, one {# commentaire} other {# commentaires}} (ne doit pas rentrer en conflit avec la traduction pr\u00e9c\u00e9dente)"}}}; -export const POST_NUM_COMMENTS_2 = {"id":"post.num_comments..","translations":{"messages+intl-icu":{"en":"{count, plural, one {# comment} other {# comments}} (should not conflict with the previous one.)","fr":"{count, plural, one {# commentaire} other {# commentaires}} (ne doit pas rentrer en conflit avec la traduction pr\u00e9c\u00e9dente)"}}}; -export const SYMFONY_GREAT = {"id":"symfony.great","translations":{"messages":{"en":"Symfony is awesome!","fr":"Symfony est g\u00e9nial !"}}}; -export const SYMFONY_WHAT = {"id":"symfony.what","translations":{"messages":{"en":"Symfony is %what%!","fr":"Symfony est %what%!"}}}; -export const SYMFONY_WHAT_1 = {"id":"symfony.what!","translations":{"messages":{"en":"Symfony is %what%! (should not conflict with the previous one.)","fr":"Symfony est %what%! (ne doit pas rentrer en conflit avec la traduction pr\u00e9c\u00e9dente)"}}}; -export const SYMFONY_WHAT_2 = {"id":"symfony.what.","translations":{"messages":{"en":"Symfony is %what%. (should also not conflict with the previous one.)","fr":"Symfony est %what%. (ne doit pas non plus rentrer en conflit avec la traduction pr\u00e9c\u00e9dente)"}}}; -export const APPLES_COUNT0 = {"id":"apples.count.0","translations":{"messages":{"en":"There is 1 apple|There are %count% apples","fr":"Il y a 1 pomme|Il y a %count% pommes"}}}; -export const APPLES_COUNT1 = {"id":"apples.count.1","translations":{"messages":{"en":"{1} There is one apple|]1,Inf] There are %count% apples","fr":"{1} Il y a une pomme|]1,Inf] Il y a %count% pommes"}}}; -export const APPLES_COUNT2 = {"id":"apples.count.2","translations":{"messages":{"en":"{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples","fr":"{0} Il n'y a pas de pommes|{1} Il y a une pomme|]1,Inf] Il y a %count% pommes"}}}; -export const APPLES_COUNT3 = {"id":"apples.count.3","translations":{"messages":{"en":"one: There is one apple|more: There are %count% apples","fr":"one: Il y a une pomme|more: Il y a %count% pommes"}}}; -export const APPLES_COUNT4 = {"id":"apples.count.4","translations":{"messages":{"en":"one: There is one apple|more: There are more than one apple","fr":"one: Il y a une pomme|more: Il y a plus d'une pomme"}}}; -export const WHAT_COUNT1 = {"id":"what.count.1","translations":{"messages":{"en":"{1} There is one %what%|]1,Inf] There are %count% %what%","fr":"{1} Il y a une %what%|]1,Inf] Il y a %count% %what%"}}}; -export const WHAT_COUNT2 = {"id":"what.count.2","translations":{"messages":{"en":"{0} There are no %what%|{1} There is one %what%|]1,Inf] There are %count% %what%","fr":"{0} Il n'y a pas de %what%|{1} Il y a une %what%|]1,Inf] Il y a %count% %what%"}}}; -export const WHAT_COUNT3 = {"id":"what.count.3","translations":{"messages":{"en":"one: There is one %what%|more: There are %count% %what%","fr":"one: Il y a une %what%|more: Il y a %count% %what%"}}}; -export const WHAT_COUNT4 = {"id":"what.count.4","translations":{"messages":{"en":"one: There is one %what%|more: There are more than one %what%","fr":"one: Il y a une %what%|more: Il y a more than one %what%"}}}; -export const ANIMAL_DOG_CAT = {"id":"animal.dog-cat","translations":{"messages":{"en":"Dog and cat","fr":"Chien et chat"}}}; -export const ANIMAL_DOG_CAT_1 = {"id":"animal.dog_cat","translations":{"messages":{"en":"Dog and cat (should not conflict with the previous one)","fr":"Chien et chat (ne doit pas rentrer en conflit avec la traduction pr\u00e9c\u00e9dente)"}}}; -export const _0STARTS_WITH_NUMERIC = {"id":"0starts.with.numeric","translations":{"messages":{"en":"Key starts with numeric char","fr":"La touche commence par un caract\u00e8re num\u00e9rique"}}}; - -JAVASCRIPT); + export const NOTIFICATION_COMMENT_CREATED = {"id":"notification.comment_created","translations":{"messages+intl-icu":{"en":"Your post received a comment!","fr":"Votre article a re\u00e7u un commentaire !"}}}; + export const NOTIFICATION_COMMENT_CREATED_DESCRIPTION = {"id":"notification.comment_created.description","translations":{"messages+intl-icu":{"en":"Your post \"{title}\" has received a new comment. You can read the comment by following this link<\/a>","fr":"Votre article \"{title}\" a re\u00e7u un nouveau commentaire. Vous pouvez lire le commentaire en suivant ce lien<\/a>"}}}; + export const POST_NUM_COMMENTS = {"id":"post.num_comments","translations":{"messages+intl-icu":{"en":"{count, plural, one {# comment} other {# comments}}","fr":"{count, plural, one {# commentaire} other {# commentaires}}"},"foobar":{"en":"There is 1 comment|There are %count% comments","fr":"Il y a 1 comment|Il y a %count% comments"}}}; + export const POST_NUM_COMMENTS_1 = {"id":"post.num_comments.","translations":{"messages+intl-icu":{"en":"{count, plural, one {# comment} other {# comments}} (should not conflict with the previous one.)","fr":"{count, plural, one {# commentaire} other {# commentaires}} (ne doit pas rentrer en conflit avec la traduction pr\u00e9c\u00e9dente)"}}}; + export const POST_NUM_COMMENTS_2 = {"id":"post.num_comments..","translations":{"messages+intl-icu":{"en":"{count, plural, one {# comment} other {# comments}} (should not conflict with the previous one.)","fr":"{count, plural, one {# commentaire} other {# commentaires}} (ne doit pas rentrer en conflit avec la traduction pr\u00e9c\u00e9dente)"}}}; + export const SYMFONY_GREAT = {"id":"symfony.great","translations":{"messages":{"en":"Symfony is awesome!","fr":"Symfony est g\u00e9nial !"}}}; + export const SYMFONY_WHAT = {"id":"symfony.what","translations":{"messages":{"en":"Symfony is %what%!","fr":"Symfony est %what%!"}}}; + export const SYMFONY_WHAT_1 = {"id":"symfony.what!","translations":{"messages":{"en":"Symfony is %what%! (should not conflict with the previous one.)","fr":"Symfony est %what%! (ne doit pas rentrer en conflit avec la traduction pr\u00e9c\u00e9dente)"}}}; + export const SYMFONY_WHAT_2 = {"id":"symfony.what.","translations":{"messages":{"en":"Symfony is %what%. (should also not conflict with the previous one.)","fr":"Symfony est %what%. (ne doit pas non plus rentrer en conflit avec la traduction pr\u00e9c\u00e9dente)"}}}; + export const APPLES_COUNT0 = {"id":"apples.count.0","translations":{"messages":{"en":"There is 1 apple|There are %count% apples","fr":"Il y a 1 pomme|Il y a %count% pommes"}}}; + export const APPLES_COUNT1 = {"id":"apples.count.1","translations":{"messages":{"en":"{1} There is one apple|]1,Inf] There are %count% apples","fr":"{1} Il y a une pomme|]1,Inf] Il y a %count% pommes"}}}; + export const APPLES_COUNT2 = {"id":"apples.count.2","translations":{"messages":{"en":"{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples","fr":"{0} Il n'y a pas de pommes|{1} Il y a une pomme|]1,Inf] Il y a %count% pommes"}}}; + export const APPLES_COUNT3 = {"id":"apples.count.3","translations":{"messages":{"en":"one: There is one apple|more: There are %count% apples","fr":"one: Il y a une pomme|more: Il y a %count% pommes"}}}; + export const APPLES_COUNT4 = {"id":"apples.count.4","translations":{"messages":{"en":"one: There is one apple|more: There are more than one apple","fr":"one: Il y a une pomme|more: Il y a plus d'une pomme"}}}; + export const WHAT_COUNT1 = {"id":"what.count.1","translations":{"messages":{"en":"{1} There is one %what%|]1,Inf] There are %count% %what%","fr":"{1} Il y a une %what%|]1,Inf] Il y a %count% %what%"}}}; + export const WHAT_COUNT2 = {"id":"what.count.2","translations":{"messages":{"en":"{0} There are no %what%|{1} There is one %what%|]1,Inf] There are %count% %what%","fr":"{0} Il n'y a pas de %what%|{1} Il y a une %what%|]1,Inf] Il y a %count% %what%"}}}; + export const WHAT_COUNT3 = {"id":"what.count.3","translations":{"messages":{"en":"one: There is one %what%|more: There are %count% %what%","fr":"one: Il y a une %what%|more: Il y a %count% %what%"}}}; + export const WHAT_COUNT4 = {"id":"what.count.4","translations":{"messages":{"en":"one: There is one %what%|more: There are more than one %what%","fr":"one: Il y a une %what%|more: Il y a more than one %what%"}}}; + export const ANIMAL_DOG_CAT = {"id":"animal.dog-cat","translations":{"messages":{"en":"Dog and cat","fr":"Chien et chat"}}}; + export const ANIMAL_DOG_CAT_1 = {"id":"animal.dog_cat","translations":{"messages":{"en":"Dog and cat (should not conflict with the previous one)","fr":"Chien et chat (ne doit pas rentrer en conflit avec la traduction pr\u00e9c\u00e9dente)"}}}; + export const _0STARTS_WITH_NUMERIC = {"id":"0starts.with.numeric","translations":{"messages":{"en":"Key starts with numeric char","fr":"La touche commence par un caract\u00e8re num\u00e9rique"}}}; + + JAVASCRIPT); $this->assertStringEqualsFile(self::$translationsDumpDir.'/index.d.ts', <<<'TYPESCRIPT' -import { Message, NoParametersType } from '@symfony/ux-translator'; - -export declare const NOTIFICATION_COMMENT_CREATED: Message<{ 'messages+intl-icu': { parameters: NoParametersType } }, 'en'|'fr'>; -export declare const NOTIFICATION_COMMENT_CREATED_DESCRIPTION: Message<{ 'messages+intl-icu': { parameters: { 'title': string, 'link': string } } }, 'en'|'fr'>; -export declare const POST_NUM_COMMENTS: Message<{ 'messages+intl-icu': { parameters: { 'count': number } }, 'foobar': { parameters: { '%count%': number } } }, 'en'|'fr'>; -export declare const POST_NUM_COMMENTS_1: Message<{ 'messages+intl-icu': { parameters: { 'count': number } } }, 'en'|'fr'>; -export declare const POST_NUM_COMMENTS_2: Message<{ 'messages+intl-icu': { parameters: { 'count': number } } }, 'en'|'fr'>; -export declare const SYMFONY_GREAT: Message<{ 'messages': { parameters: NoParametersType } }, 'en'|'fr'>; -export declare const SYMFONY_WHAT: Message<{ 'messages': { parameters: { '%what%': string } } }, 'en'|'fr'>; -export declare const SYMFONY_WHAT_1: Message<{ 'messages': { parameters: { '%what%': string } } }, 'en'|'fr'>; -export declare const SYMFONY_WHAT_2: Message<{ 'messages': { parameters: { '%what%': string } } }, 'en'|'fr'>; -export declare const APPLES_COUNT0: Message<{ 'messages': { parameters: { '%count%': number } } }, 'en'|'fr'>; -export declare const APPLES_COUNT1: Message<{ 'messages': { parameters: { '%count%': number } } }, 'en'|'fr'>; -export declare const APPLES_COUNT2: Message<{ 'messages': { parameters: { '%count%': number } } }, 'en'|'fr'>; -export declare const APPLES_COUNT3: Message<{ 'messages': { parameters: { '%count%': number } } }, 'en'|'fr'>; -export declare const APPLES_COUNT4: Message<{ 'messages': { parameters: NoParametersType } }, 'en'|'fr'>; -export declare const WHAT_COUNT1: Message<{ 'messages': { parameters: { '%what%': string, '%count%': number } } }, 'en'|'fr'>; -export declare const WHAT_COUNT2: Message<{ 'messages': { parameters: { '%what%': string, '%count%': number } } }, 'en'|'fr'>; -export declare const WHAT_COUNT3: Message<{ 'messages': { parameters: { '%what%': string, '%count%': number } } }, 'en'|'fr'>; -export declare const WHAT_COUNT4: Message<{ 'messages': { parameters: { '%what%': string } } }, 'en'|'fr'>; -export declare const ANIMAL_DOG_CAT: Message<{ 'messages': { parameters: NoParametersType } }, 'en'|'fr'>; -export declare const ANIMAL_DOG_CAT_1: Message<{ 'messages': { parameters: NoParametersType } }, 'en'|'fr'>; -export declare const _0STARTS_WITH_NUMERIC: Message<{ 'messages': { parameters: NoParametersType } }, 'en'|'fr'>; - -TYPESCRIPT); + import { Message, NoParametersType } from '@symfony/ux-translator'; + + export declare const NOTIFICATION_COMMENT_CREATED: Message<{ 'messages+intl-icu': { parameters: NoParametersType } }, 'en'|'fr'>; + export declare const NOTIFICATION_COMMENT_CREATED_DESCRIPTION: Message<{ 'messages+intl-icu': { parameters: { 'title': string, 'link': string } } }, 'en'|'fr'>; + export declare const POST_NUM_COMMENTS: Message<{ 'messages+intl-icu': { parameters: { 'count': number } }, 'foobar': { parameters: { '%count%': number } } }, 'en'|'fr'>; + export declare const POST_NUM_COMMENTS_1: Message<{ 'messages+intl-icu': { parameters: { 'count': number } } }, 'en'|'fr'>; + export declare const POST_NUM_COMMENTS_2: Message<{ 'messages+intl-icu': { parameters: { 'count': number } } }, 'en'|'fr'>; + export declare const SYMFONY_GREAT: Message<{ 'messages': { parameters: NoParametersType } }, 'en'|'fr'>; + export declare const SYMFONY_WHAT: Message<{ 'messages': { parameters: { '%what%': string } } }, 'en'|'fr'>; + export declare const SYMFONY_WHAT_1: Message<{ 'messages': { parameters: { '%what%': string } } }, 'en'|'fr'>; + export declare const SYMFONY_WHAT_2: Message<{ 'messages': { parameters: { '%what%': string } } }, 'en'|'fr'>; + export declare const APPLES_COUNT0: Message<{ 'messages': { parameters: { '%count%': number } } }, 'en'|'fr'>; + export declare const APPLES_COUNT1: Message<{ 'messages': { parameters: { '%count%': number } } }, 'en'|'fr'>; + export declare const APPLES_COUNT2: Message<{ 'messages': { parameters: { '%count%': number } } }, 'en'|'fr'>; + export declare const APPLES_COUNT3: Message<{ 'messages': { parameters: { '%count%': number } } }, 'en'|'fr'>; + export declare const APPLES_COUNT4: Message<{ 'messages': { parameters: NoParametersType } }, 'en'|'fr'>; + export declare const WHAT_COUNT1: Message<{ 'messages': { parameters: { '%what%': string, '%count%': number } } }, 'en'|'fr'>; + export declare const WHAT_COUNT2: Message<{ 'messages': { parameters: { '%what%': string, '%count%': number } } }, 'en'|'fr'>; + export declare const WHAT_COUNT3: Message<{ 'messages': { parameters: { '%what%': string, '%count%': number } } }, 'en'|'fr'>; + export declare const WHAT_COUNT4: Message<{ 'messages': { parameters: { '%what%': string } } }, 'en'|'fr'>; + export declare const ANIMAL_DOG_CAT: Message<{ 'messages': { parameters: NoParametersType } }, 'en'|'fr'>; + export declare const ANIMAL_DOG_CAT_1: Message<{ 'messages': { parameters: NoParametersType } }, 'en'|'fr'>; + export declare const _0STARTS_WITH_NUMERIC: Message<{ 'messages': { parameters: NoParametersType } }, 'en'|'fr'>; + + TYPESCRIPT); } public function testDumpWithExcludedDomains() diff --git a/src/TwigComponent/src/Command/TwigComponentDebugCommand.php b/src/TwigComponent/src/Command/TwigComponentDebugCommand.php index f883f59ef96..85b0f291ae4 100644 --- a/src/TwigComponent/src/Command/TwigComponentDebugCommand.php +++ b/src/TwigComponent/src/Command/TwigComponentDebugCommand.php @@ -52,16 +52,16 @@ protected function configure(): void ]) ->setHelp( <<<'EOF' -The %command.name% display all the Twig components in your application. + The %command.name% display all the Twig components in your application. -To list all components: + To list all components: - php %command.full_name% + php %command.full_name% -To get specific information about a component, specify its name (or a part of it): + To get specific information about a component, specify its name (or a part of it): - php %command.full_name% Alert -EOF + php %command.full_name% Alert + EOF ); } diff --git a/src/TwigComponent/src/DependencyInjection/Compiler/TwigComponentPass.php b/src/TwigComponent/src/DependencyInjection/Compiler/TwigComponentPass.php index b39ae4535dc..9accecbeef5 100644 --- a/src/TwigComponent/src/DependencyInjection/Compiler/TwigComponentPass.php +++ b/src/TwigComponent/src/DependencyInjection/Compiler/TwigComponentPass.php @@ -69,7 +69,7 @@ public function process(ContainerBuilder $container): void $tag['service_id'] = $id; $tag['class'] = $definition->getClass(); - $tag['template'] = $tag['template'] ?? $this->calculateTemplate($tag['key'], $defaults); + $tag['template'] ??= $this->calculateTemplate($tag['key'], $defaults); $componentConfig[$tag['key']] = [...$tag, ...$this->getMountMethods($tag['class'])]; $componentReferences[$tag['key']] = new Reference($id); $componentNames[] = $tag['key']; diff --git a/src/TwigComponent/tests/Integration/ComponentExtensionTest.php b/src/TwigComponent/tests/Integration/ComponentExtensionTest.php index 4c055dbe827..81cd3fdcefd 100644 --- a/src/TwigComponent/tests/Integration/ComponentExtensionTest.php +++ b/src/TwigComponent/tests/Integration/ComponentExtensionTest.php @@ -237,14 +237,14 @@ public static function renderingAttributesManuallyProvider(): iterable yield [ ['class' => 'block'], << - HTML, +
    + HTML, ]; yield [ @@ -256,14 +256,14 @@ class="block" 'qux' => 'value', ], << - HTML, +
    + HTML, ]; } @@ -285,15 +285,15 @@ public function testRenderingComponentWithNestedAttributes() $this->assertSame( << -
    - -
    - - -
    - - HTML, +
    +
    + +
    + + +
    +
    + HTML, trim($output) ); @@ -305,15 +305,15 @@ public function testRenderingComponentWithNestedAttributes() $this->assertSame( << -
    - -
    - - -
    - - HTML, +
    +
    + +
    + + +
    +
    + HTML, trim($output) ); } @@ -380,15 +380,15 @@ public function testRenderingHtmlSyntaxComponentWithNestedAttributes() $this->assertSame( << -
    - -
    - - -
    - - HTML, +
    +
    + +
    + + +
    +
    + HTML, trim($output) ); @@ -400,15 +400,15 @@ public function testRenderingHtmlSyntaxComponentWithNestedAttributes() $this->assertSame( << -
    - -
    - - -
    - - HTML, +
    +
    + +
    + + +
    +
    + HTML, trim($output) ); } diff --git a/src/TwigComponent/tests/Unit/TwigPreLexerTest.php b/src/TwigComponent/tests/Unit/TwigPreLexerTest.php index fc665aceb41..c056c5ffea1 100644 --- a/src/TwigComponent/tests/Unit/TwigPreLexerTest.php +++ b/src/TwigComponent/tests/Unit/TwigPreLexerTest.php @@ -160,140 +160,140 @@ public static function getLexTests(): iterable ]; yield 'component_where_entire_default_block_is_embedded_component' => [ << - bar content - - EOF, + + bar content + + EOF, << [ << - - - EOF, + + + + EOF, << [ << -

    - {% embed "my_embed.html.twig" with { foo: 'bar' } %}{% endembed %} -

    - - EOF, + +

    + {% embed "my_embed.html.twig" with { foo: 'bar' } %}{% endembed %} +

    +
    + EOF, << - {% embed "my_embed.html.twig" with { foo: 'bar' } %}{% endembed %} -

    - {% endblock %}{% endcomponent %} - EOF, + {% component 'Alert' %} + {% block content %}

    + {% embed "my_embed.html.twig" with { foo: 'bar' } %}{% endembed %} +

    + {% endblock %}{% endcomponent %} + EOF, ]; yield 'component_where_entire_default_block_is_twig_embed_with_block_string' => [ << -

    - {% embed "my_embed.html.twig" %} - {% block my_embed_block "foo" %} - {% endembed %} -

    - - EOF, + +

    + {% embed "my_embed.html.twig" %} + {% block my_embed_block "foo" %} + {% endembed %} +

    +
    + EOF, << - {% embed "my_embed.html.twig" %} - {% block my_embed_block "foo" %} - {% endembed %} -

    - {% endblock %}{% endcomponent %} - EOF, + {% component 'Alert' %} + {% block content %}

    + {% embed "my_embed.html.twig" %} + {% block my_embed_block "foo" %} + {% endembed %} +

    + {% endblock %}{% endcomponent %} + EOF, ]; yield 'component_where_entire_default_block_is_twig_embed_with_block_variable' => [ << -

    - {% embed "my_embed.html.twig" %} - {% block my_embed_block fooVar %} - {% endembed %} -

    - - EOF, + +

    + {% embed "my_embed.html.twig" %} + {% block my_embed_block fooVar %} + {% endembed %} +

    +
    + EOF, << - {% embed "my_embed.html.twig" %} - {% block my_embed_block fooVar %} - {% endembed %} -

    - {% endblock %}{% endcomponent %} - EOF, + {% component 'Alert' %} + {% block content %}

    + {% embed "my_embed.html.twig" %} + {% block my_embed_block fooVar %} + {% endembed %} +

    + {% endblock %}{% endcomponent %} + EOF, ]; yield 'component_where_entire_default_block_is_twig_embed_with_block_expanded' => [ << -

    - {% embed "my_embed.html.twig" %} - {% block my_embed_block %}bar{% endblock %} - {% endembed %} -

    - - EOF, + +

    + {% embed "my_embed.html.twig" %} + {% block my_embed_block %}bar{% endblock %} + {% endembed %} +

    +
    + EOF, << - {% embed "my_embed.html.twig" %} - {% block my_embed_block %}bar{% endblock %} - {% endembed %} -

    - {% endblock %}{% endcomponent %} - EOF, + {% component 'Alert' %} + {% block content %}

    + {% embed "my_embed.html.twig" %} + {% block my_embed_block %}bar{% endblock %} + {% endembed %} +

    + {% endblock %}{% endcomponent %} + EOF, ]; yield 'component_where_entire_default_block_is_twig_embed_with_block_variable_and_manipulations' => [ << -

    - {% embed "my_embed.html.twig" %} - {% block my_embed_block doSomething(fooVar)|u.camel.title.truncate(5) %} - {% endembed %} -

    - - EOF, + +

    + {% embed "my_embed.html.twig" %} + {% block my_embed_block doSomething(fooVar)|u.camel.title.truncate(5) %} + {% endembed %} +

    +
    + EOF, << - {% embed "my_embed.html.twig" %} - {% block my_embed_block doSomething(fooVar)|u.camel.title.truncate(5) %} - {% endembed %} -

    - {% endblock %}{% endcomponent %} - EOF, + {% component 'Alert' %} + {% block content %}

    + {% embed "my_embed.html.twig" %} + {% block my_embed_block doSomething(fooVar)|u.camel.title.truncate(5) %} + {% endembed %} +

    + {% endblock %}{% endcomponent %} + EOF, ]; yield 'string_inside_of_twig_code_not_escaped' => [ << - EOF, + + EOF, << [ @@ -382,59 +382,59 @@ public static function getLexTests(): iterable ]; yield 'component_with_comment_line_between_args' => [ << - TWIG, + + TWIG, '{{ component(\'foo\', { bar: \'baz\' }) }}', ]; yield 'component_with_comment_lines_between_args' => [ << - TWIG, + + TWIG, '{{ component(\'foo\', { foo: \'foo\', bar: \'bar\' }) }}', ]; yield 'component_with_comment_line_containing_ending_tag' => [ << - bar="bar" - /> - TWIG, + + bar="bar" + /> + TWIG, '{{ component(\'foo\', { bar: \'bar\' }) }}', ]; yield 'component_with_comment_line_in_argument_value' => [ << - TWIG, + + TWIG, '{{ component(\'foo\', { bar: \'# bar\' }) }}', ]; yield 'component_with_comment_line_in_argument_array_value_is_kept' => [ << - TWIG, + + TWIG, // Twig will remove the comment, we don't need to remove it <<