diff --git a/.github/workflows/code_analysis.yaml b/.github/workflows/code_analysis.yaml index 7b6523a6cdf..9e0d1107441 100644 --- a/.github/workflows/code_analysis.yaml +++ b/.github/workflows/code_analysis.yaml @@ -36,13 +36,9 @@ jobs: name: 'PHP Linter' run: vendor/bin/parallel-lint src tests - - - name: 'Check Commented Code' - run: vendor/bin/easy-ci check-commented-code src tests --ansi - - name: 'Check Active Classes' - run: vendor/bin/class-leak check src --ansi --skip-type="\Symplify\PhpConfigPrinter\Contract\NodeVisitor\PrePrintNodeVisitorInterface" + run: vendor/bin/class-leak check bin src --ansi --skip-type="\Symplify\PhpConfigPrinter\Contract\NodeVisitor\PrePrintNodeVisitorInterface" name: ${{ matrix.actions.name }} diff --git a/.gitignore b/.gitignore index d026490bac9..652511177c3 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,6 @@ composer.lock /vendor .phpunit.cache + +# kernel cache +/var diff --git a/README.md b/README.md index f40b71a890e..9066ec47b59 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Convert Symfony XML/YAML configs to PHP +# Convert Symfony YAML configs to PHP [![Downloads total](https://img.shields.io/packagist/dt/symplify/config-transformer.svg?style=flat-square)](https://packagist.org/packages/symplify/config-transformer/stats) diff --git a/bin/config-transformer.php b/bin/config-transformer.php index 1cedf79f0a3..62d283c7bc1 100755 --- a/bin/config-transformer.php +++ b/bin/config-transformer.php @@ -2,8 +2,9 @@ declare(strict_types=1); +use Symfony\Component\Console\Input\ArgvInput; +use Symfony\Component\Console\Output\ConsoleOutput; use Symplify\ConfigTransformer\Kernel\ConfigTransformerKernel; -use Symplify\SymplifyKernel\ValueObject\KernelBootAndApplicationRun; $possibleAutoloadPaths = [ // dependency @@ -26,6 +27,13 @@ require_once $scoperAutoloadFilepath; } +$configTransformerKernel = new ConfigTransformerKernel(); +$configTransformerKernel->boot(); -$kernelBootAndApplicationRun = new KernelBootAndApplicationRun(ConfigTransformerKernel::class); -$kernelBootAndApplicationRun->run(); +$container = $configTransformerKernel->getContainer(); + +$configTransformerApplication = $container->get(\Symplify\ConfigTransformer\Console\ConfigTransformerApplication::class); + +$input = new ArgvInput(); +$output = new ConsoleOutput(); +$configTransformerApplication->run($input, $output); diff --git a/composer.json b/composer.json index b4aa4f601f3..fb9bd1e27ad 100644 --- a/composer.json +++ b/composer.json @@ -7,34 +7,29 @@ ], "require": { "php": ">=8.1", - "ext-dom": "*", "nette/utils": "^3.2", - "nikic/php-parser": "^4.17.1", - "symfony/console": "^6.3", + "symfony/config": "^6.4", + "symfony/console": "^6.4", "symfony/dependency-injection": "6.1.*", - "symfony/expression-language": "^6.2", - "symfony/yaml": "^6.2", - "symplify/package-builder": "^11.3", - "symplify/php-config-printer": "^11.1", - "symplify/symplify-kernel": "^11.1" + "symfony/expression-language": "^6.4", + "symfony/filesystem": "^6.4", + "symfony/finder": "^6.4", + "symfony/http-kernel": "^6.1", + "symfony/yaml": "^6.4", + "symplify/php-config-printer": "^11.3.6", + "webmozart/assert": "^1.11" }, "require-dev": { "cweagans/composer-patches": "^1.7", "php-parallel-lint/php-parallel-lint": "^1.3", - "phpstan/extension-installer": "^1.2", - "phpstan/phpstan": "^1.9", - "phpunit/phpunit": "^10.0", - "rector/rector": "^0.15.10", - "symfony/framework-bundle": "^6.1", - "symplify/easy-ci": "^11.1", - "symplify/easy-coding-standard": "^11.1", - "symplify/easy-testing": "^11.1", - "symplify/monorepo-builder": "^11.2", - "symplify/phpstan-extensions": "^11.1", - "symplify/vendor-patches": "^11.2", - "tomasvotruba/class-leak": "0.1.1.72", - "tomasvotruba/type-coverage": "^0.2", - "tomasvotruba/unused-public": "^0.1" + "phpstan/extension-installer": "^1.3", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5", + "rector/rector": "^0.18.12", + "symplify/easy-coding-standard": "^12.0", + "symplify/phpstan-extensions": "^11.4", + "symplify/vendor-patches": "^11.3", + "tomasvotruba/class-leak": "^0.2.6" }, "autoload": { "psr-4": { @@ -67,7 +62,6 @@ "check-cs": "vendor/bin/ecs check --ansi", "fix-cs": "vendor/bin/ecs check --fix --ansi", "phpstan": "vendor/bin/phpstan analyse --ansi --error-format symplify", - "rector": "vendor/bin/rector process --dry-run --ansi", - "release": "vendor/bin/monorepo-builder release patch --ansi" + "rector": "vendor/bin/rector process --dry-run --ansi" } } diff --git a/config/config.php b/config/config.php index e876a7ba277..b086e61487b 100644 --- a/config/config.php +++ b/config/config.php @@ -2,18 +2,9 @@ declare(strict_types=1); -use PhpParser\BuilderFactory; -use PhpParser\NodeFinder; -use SebastianBergmann\Diff\Differ; -use Symfony\Component\Console\Application; +use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; -use Symfony\Component\Yaml\Parser; -use Symplify\ConfigTransformer\Console\ConfigTransformerApplication; -use Symplify\PackageBuilder\Console\Formatter\ColorConsoleDiffFormatter; -use Symplify\PackageBuilder\Console\Output\ConsoleDiffer; -use Symplify\PackageBuilder\Diff\DifferFactory; -use Symplify\PackageBuilder\Reflection\ClassLikeExistenceChecker; -use Symplify\PackageBuilder\Yaml\ParametersMerger; +use Symplify\ConfigTransformer\Console\Style\SymfonyStyleFactory; use function Symfony\Component\DependencyInjection\Loader\Configurator\service; return static function (ContainerConfigurator $containerConfigurator): void { @@ -21,7 +12,8 @@ $services->defaults() ->public() - ->autowire(); + ->autowire() + ->autoconfigure(); $services->load('Symplify\ConfigTransformer\\', __DIR__ . '/../src') ->exclude([ @@ -31,22 +23,6 @@ __DIR__ . '/../src/ValueObject', ]); - // console - $services->alias(Application::class, ConfigTransformerApplication::class); - - // color diff - $services->set(DifferFactory::class); - $services->set(Differ::class) - ->factory([service(DifferFactory::class), 'create']); - - $services->set(ConsoleDiffer::class); - - $services->set(ColorConsoleDiffFormatter::class); - - $services->set(BuilderFactory::class); - $services->set(NodeFinder::class); - $services->set(Parser::class); - - $services->set(ClassLikeExistenceChecker::class); - $services->set(ParametersMerger::class); + $services->set(SymfonyStyle::class) + ->factory([service(SymfonyStyleFactory::class), 'create']); }; diff --git a/phpstan.neon b/phpstan.neon index ba4806435e9..02c9e3ebb77 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -10,11 +10,6 @@ parameters: - '*/tests/**/Source/*' - '*/tests/**/Fixture/*' - unused_public: - methods: true - properties: true - constants: true - ignoreErrors: - message: '#Parameter \#1 \$commandName of method Symfony\\Component\\Console\\Application\:\:setDefaultCommand\(\) expects string, string\|null given#' diff --git a/src/Collector/XmlImportCollector.php b/src/Collector/XmlImportCollector.php deleted file mode 100644 index 20272134e32..00000000000 --- a/src/Collector/XmlImportCollector.php +++ /dev/null @@ -1,31 +0,0 @@ - - */ - private array $imports = []; - - public function addImport(mixed $resource, bool|string $ignoreErrors): void - { - $this->imports[] = [ - YamlKey::RESOURCE => $resource, - YamlKey::IGNORE_ERRORS => $ignoreErrors, - ]; - } - - /** - * @return array - */ - public function provide(): array - { - return $this->imports; - } -} diff --git a/src/ConfigLoader.php b/src/ConfigLoader.php index 6340518c2fd..ef25f25f43d 100644 --- a/src/ConfigLoader.php +++ b/src/ConfigLoader.php @@ -4,6 +4,7 @@ namespace Symplify\ConfigTransformer; +use Nette\Utils\FileSystem; use Nette\Utils\Strings; use Symfony\Component\Config\Exception\LoaderLoadException; use Symfony\Component\Config\FileLocator; @@ -14,15 +15,13 @@ use Symfony\Component\DependencyInjection\Loader\DirectoryLoader; use Symfony\Component\DependencyInjection\Loader\GlobFileLoader; use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; +use Symfony\Component\Finder\SplFileInfo; use Symplify\ConfigTransformer\DependencyInjection\ExtensionFaker; use Symplify\ConfigTransformer\DependencyInjection\Loader\MissingAutodiscoveryDirectoryTolerantYamlFileLoader; use Symplify\ConfigTransformer\DependencyInjection\Loader\SkippingPhpFileLoader; -use Symplify\ConfigTransformer\DependencyInjection\LoaderFactory\IdAwareXmlFileLoaderFactory; use Symplify\ConfigTransformer\Enum\Format; use Symplify\ConfigTransformer\Exception\NotImplementedYetException; use Symplify\ConfigTransformer\ValueObject\ContainerBuilderAndFileContent; -use Symplify\SmartFileSystem\SmartFileInfo; -use Symplify\SmartFileSystem\SmartFileSystem; final class ConfigLoader { @@ -30,7 +29,7 @@ final class ConfigLoader * @see https://regex101.com/r/4Uanps/4 * @var string */ - private const PHP_CONST_REGEX = '#!php/const:?\s*([a-zA-Z0-9_\\\\]+(::[a-zA-Z0-9_]+)?)+(:\s*(.*))?#'; + private const PHP_CONST_REGEX = '#!php/const:?\s*([a-zA-Z0-9_\\\]+(::\w+)?)+(:\s*(.*))?#'; /** * @see https://regex101.com/r/spi4ir/1 @@ -39,18 +38,16 @@ final class ConfigLoader private const UNQUOTED_PARAMETER_REGEX = '#^(\s*\w+:\s+)(\%(.*?)%)(.*?)?$#m'; public function __construct( - private readonly IdAwareXmlFileLoaderFactory $idAwareXmlFileLoaderFactory, - private readonly SmartFileSystem $smartFileSystem, private readonly ExtensionFaker $extensionFaker ) { } public function createAndLoadContainerBuilderFromFileInfo( - SmartFileInfo $smartFileInfo, + SplFileInfo $smartFileInfo, ): ContainerBuilderAndFileContent { $containerBuilder = new ContainerBuilder(); - $delegatingLoader = $this->createLoaderBySuffix($containerBuilder, $smartFileInfo->getSuffix()); + $delegatingLoader = $this->createLoaderBySuffix($containerBuilder, $smartFileInfo->getExtension()); $fileRealPath = $smartFileInfo->getRealPath(); // correct old syntax of tags so we can parse it @@ -63,7 +60,7 @@ public function createAndLoadContainerBuilderFromFileInfo( static fn (array $match): string => $match[1] . '"' . $match[2] . ($match[4] ?? '') . '"' ); - if (in_array($smartFileInfo->getSuffix(), [Format::YML, Format::YAML], true)) { + if (in_array($smartFileInfo->getExtension(), [Format::YML, Format::YAML], true)) { $content = Strings::replace( $content, self::PHP_CONST_REGEX, @@ -75,7 +72,7 @@ public function createAndLoadContainerBuilderFromFileInfo( ); if ($content !== $smartFileInfo->getContents()) { $fileRealPath = sys_get_temp_dir() . '/__symplify_config_tranformer_clean_yaml/' . $smartFileInfo->getFilename(); - $this->smartFileSystem->dumpFile($fileRealPath, $content); + FileSystem::write($fileRealPath, $content); } $this->extensionFaker->fakeInContainerBuilder($containerBuilder, $content); @@ -93,11 +90,6 @@ public function createAndLoadContainerBuilderFromFileInfo( private function createLoaderBySuffix(ContainerBuilder $containerBuilder, string $suffix): DelegatingLoader { - if ($suffix === Format::XML) { - $idAwareXmlFileLoader = $this->idAwareXmlFileLoaderFactory->createFromContainerBuilder($containerBuilder); - return $this->wrapToDelegatingLoader($idAwareXmlFileLoader, $containerBuilder); - } - if (in_array($suffix, [Format::YML, Format::YAML], true)) { $missingAutodiscoveryDirectoryTolerantYamlFileLoader = new MissingAutodiscoveryDirectoryTolerantYamlFileLoader( $containerBuilder, diff --git a/src/Console/ColorConsoleDiffFormatter.php b/src/Console/ColorConsoleDiffFormatter.php new file mode 100644 index 00000000000..280bcd84f7e --- /dev/null +++ b/src/Console/ColorConsoleDiffFormatter.php @@ -0,0 +1,102 @@ + + */ +final class ColorConsoleDiffFormatter +{ + /** + * @var string + * @see https://regex101.com/r/ovLMDF/1 + */ + private const PLUS_START_REGEX = '#^(\+.*)#'; + + /** + * @var string + * @see https://regex101.com/r/xwywpa/1 + */ + private const MINUT_START_REGEX = '#^(\-.*)#'; + + /** + * @var string + * @see https://regex101.com/r/CMlwa8/1 + */ + private const AT_START_REGEX = '#^(@.*)#'; + + /** + * @var string + * @see https://regex101.com/r/qduj2O/1 + */ + private const NEWLINES_REGEX = "#\n\r|\n#"; + + private readonly string $template; + + public function __construct() + { + $this->template = sprintf( + ' ---------- begin diff ----------%s%%s%s ----------- end diff -----------' . PHP_EOL, + PHP_EOL, + PHP_EOL + ); + } + + public function format(string $diff): string + { + return $this->formatWithTemplate($diff, $this->template); + } + + private function formatWithTemplate(string $diff, string $template): string + { + $escapedDiff = OutputFormatter::escape(rtrim($diff)); + + $escapedDiffLines = Strings::split($escapedDiff, self::NEWLINES_REGEX); + + // remove description of added + remove; obvious on diffs + foreach ($escapedDiffLines as $key => $escapedDiffLine) { + if ($escapedDiffLine === '--- Original') { + unset($escapedDiffLines[$key]); + } + + if ($escapedDiffLine === '+++ New') { + unset($escapedDiffLines[$key]); + } + } + + $coloredLines = array_map(function (string $string): string { + $string = $this->makePlusLinesGreen($string); + $string = $this->makeMinusLinesRed($string); + $string = $this->makeAtNoteCyan($string); + + if ($string === ' ') { + return ''; + } + + return $string; + }, $escapedDiffLines); + + return sprintf($template, implode(PHP_EOL, $coloredLines)); + } + + private function makePlusLinesGreen(string $string): string + { + return Strings::replace($string, self::PLUS_START_REGEX, '$1'); + } + + private function makeMinusLinesRed(string $string): string + { + return Strings::replace($string, self::MINUT_START_REGEX, '$1'); + } + + private function makeAtNoteCyan(string $string): string + { + return Strings::replace($string, self::AT_START_REGEX, '$1'); + } +} diff --git a/src/Command/SwitchFormatCommand.php b/src/Console/Command/SwitchFormatCommand.php similarity index 88% rename from src/Command/SwitchFormatCommand.php rename to src/Console/Command/SwitchFormatCommand.php index 46ec7513349..fe1c0e2e8b6 100644 --- a/src/Command/SwitchFormatCommand.php +++ b/src/Console/Command/SwitchFormatCommand.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Symplify\ConfigTransformer\Command; +namespace Symplify\ConfigTransformer\Console\Command; use Nette\Utils\FileSystem; use Symfony\Component\Console\Command\Command; @@ -12,6 +12,7 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Finder\Finder; +use Symfony\Component\Finder\SplFileInfo; use Symplify\ConfigTransformer\Configuration\ConfigurationFactory; use Symplify\ConfigTransformer\Converter\ConfigFormatConverter; use Symplify\ConfigTransformer\FileSystem\ConfigFileDumper; @@ -19,7 +20,6 @@ use Symplify\ConfigTransformer\ValueObject\Configuration; use Symplify\ConfigTransformer\ValueObject\ConvertedContent; use Symplify\ConfigTransformer\ValueObject\Option; -use Symplify\SmartFileSystem\SmartFileInfo; final class SwitchFormatCommand extends Command { @@ -38,17 +38,17 @@ protected function configure(): void $this->setName('switch-format'); $this->setAliases(['convert', 'transform']); - $this->setDescription('Converts XML/YAML configs to PHP format'); + $this->setDescription('Converts YAML configs to PHP format'); $this->addArgument( Option::SOURCES, InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Path to directory/file with configs', // 99 % of symfony project has this directory - [getcwd() . '/config'] + [getcwd() . '/config', getcwd() . '/app/config'] ); - $this->addOption(Option::DRY_RUN, 'n', InputOption::VALUE_NONE, 'Dry run - no removal or config change'); + $this->addOption(Option::DRY_RUN, null, InputOption::VALUE_NONE, 'Dry run - no removal or config change'); } protected function execute(InputInterface $input, OutputInterface $output): int @@ -57,9 +57,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int $totalFileCount = $this->getTotalFileCount($configuration); - $fileInfos = $this->configFileFinder->findFileInfos($configuration); + $fileInfos = $this->configFileFinder->findFileInfos($configuration->getSources()); if ($fileInfos === []) { - $successMessage = sprintf('No YAML/XML configs found in %d files, good job!', $totalFileCount); + $successMessage = sprintf('No YAML configs found in %d files, good job!', $totalFileCount); $this->symfonyStyle->success($successMessage); return self::SUCCESS; @@ -89,7 +89,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int return self::SUCCESS; } - private function removeFileInfo(Configuration $configuration, SmartFileInfo $fileInfo): void + private function removeFileInfo(Configuration $configuration, SplFileInfo $fileInfo): void { // only dry run, nothing to remove if ($configuration->isDryRun()) { diff --git a/src/Console/ConfigTransformerApplication.php b/src/Console/ConfigTransformerApplication.php index 1a501ddcfb5..6dd803ed9ed 100644 --- a/src/Console/ConfigTransformerApplication.php +++ b/src/Console/ConfigTransformerApplication.php @@ -5,7 +5,7 @@ namespace Symplify\ConfigTransformer\Console; use Symfony\Component\Console\Application; -use Symplify\ConfigTransformer\Command\SwitchFormatCommand; +use Symplify\ConfigTransformer\Console\Command\SwitchFormatCommand; final class ConfigTransformerApplication extends Application { @@ -17,7 +17,11 @@ public function __construct(SwitchFormatCommand $switchFormatCommand) $this->add($switchFormatCommand); - // make single command application - $this->setDefaultCommand($switchFormatCommand->getName(), true); + // hid unnecesary command + $this->get('help')->setHidden(); + $this->get('completion')->setHidden(); + + // make single command application for fast run + $this->setDefaultCommand($switchFormatCommand->getName()); } } diff --git a/src/Console/ConsoleDiffer.php b/src/Console/ConsoleDiffer.php new file mode 100644 index 00000000000..c8d42d8a896 --- /dev/null +++ b/src/Console/ConsoleDiffer.php @@ -0,0 +1,33 @@ +createDiffer(); + + $diff = $differ->diff($old, $new); + return $this->colorConsoleDiffFormatter->format($diff); + } + + private function createDiffer(): Differ + { + $unifiedDiffOutputBuilder = new UnifiedDiffOutputBuilder(''); + PrivatesAccessor::writePrivateProperty($unifiedDiffOutputBuilder, 'contextLines', 10000); + + return new Differ($unifiedDiffOutputBuilder); + } +} diff --git a/src/Console/Style/SymfonyStyleFactory.php b/src/Console/Style/SymfonyStyleFactory.php new file mode 100644 index 00000000000..3435395cffe --- /dev/null +++ b/src/Console/Style/SymfonyStyleFactory.php @@ -0,0 +1,20 @@ +currentFilePathProvider->setFilePath($smartFileInfo->getRealPath()); + $this->currentFilePathProvider->setFilePath($fileInfo->getRealPath()); $containerBuilderAndFileContent = $this->configLoader->createAndLoadContainerBuilderFromFileInfo( - $smartFileInfo + $fileInfo ); - $containerBuilder = $containerBuilderAndFileContent->getContainerBuilder(); - - if (in_array($smartFileInfo->getSuffix(), [Format::YAML, Format::YML], true)) { + if (in_array($fileInfo->getExtension(), [Format::YAML, Format::YML], true)) { $dumpedYaml = $containerBuilderAndFileContent->getFileContent(); - $dumpedYaml = $this->decorateWithCollectedXmlImports($dumpedYaml); - - return $this->yamlToPhpConverter->convert($dumpedYaml, $smartFileInfo->getRealPath()); + return $this->yamlToPhpConverter->convert($dumpedYaml, $fileInfo->getRealPath()); } - if ($smartFileInfo->getSuffix() === Format::XML) { - $dumpedYaml = $this->dumpContainerBuilderToYaml($containerBuilder); - $dumpedYaml = $this->decorateWithCollectedXmlImports($dumpedYaml); - - return $this->yamlToPhpConverter->convert($dumpedYaml, $smartFileInfo->getRealPath()); - } - - $message = sprintf('Suffix "%s" is not support yet', $smartFileInfo->getSuffix()); + $message = sprintf('Suffix "%s" is not support yet', $fileInfo->getExtension()); throw new NotImplementedYetException($message); } - - private function dumpContainerBuilderToYaml(ContainerBuilder $containerBuilder): string - { - $yamlDumper = new YamlDumper($containerBuilder); - $this->containerBuilderCleaner->cleanContainerBuilder($containerBuilder); - - // 1. services and parameters - $content = $yamlDumper->dump(); - if (! is_string($content)) { - throw new ShouldNotHappenException(); - } - - // 2. append extension yaml too - /** @var array $extensionsConfigs */ - $extensionsConfigs = $this->privatesAccessor->getPrivateProperty($containerBuilder, 'extensionConfigs'); - foreach ($extensionsConfigs as $namespace => $configs) { - $mergedConfig = []; - foreach ($configs as $config) { - $mergedConfig = $this->parametersMerger->merge($mergedConfig, $config); - } - - $extensionsConfigs[$namespace] = $mergedConfig; - } - - $extensionsContent = $this->dumpYaml($extensionsConfigs); - - return $content . PHP_EOL . $extensionsContent; - } - - private function decorateWithCollectedXmlImports(string $dumpedYaml): string - { - $collectedXmlImports = $this->xmlImportCollector->provide(); - if ($collectedXmlImports === []) { - return $dumpedYaml; - } - - /** @var array $yamlArray */ - $yamlArray = Yaml::parse($dumpedYaml, Yaml::PARSE_CUSTOM_TAGS); - $yamlArray['imports'] = array_merge($yamlArray['imports'] ?? [], $collectedXmlImports); - - return $this->dumpYaml($yamlArray); - } - - /** - * @param array $yamlArray - */ - private function dumpYaml(array $yamlArray): string - { - if ($yamlArray === []) { - return ''; - } - - return Yaml::dump($yamlArray, 10, 4, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK); - } } diff --git a/src/Converter/YamlToPhpConverter.php b/src/Converter/YamlToPhpConverter.php index a1ee1a080b5..09245612269 100644 --- a/src/Converter/YamlToPhpConverter.php +++ b/src/Converter/YamlToPhpConverter.php @@ -14,8 +14,6 @@ /** * @api - * @source https://raw.githubusercontent.com/archeoprog/maker-bundle/make-convert-services/src/Util/PhpServicesCreator.php - * * @see \Symplify\ConfigTransformer\Tests\Converter\YamlToPhpConverter\YamlToPhpConverterTest */ final class YamlToPhpConverter diff --git a/src/DependencyInjection/ContainerBuilderCleaner.php b/src/DependencyInjection/ContainerBuilderCleaner.php deleted file mode 100644 index 8d494aa71cb..00000000000 --- a/src/DependencyInjection/ContainerBuilderCleaner.php +++ /dev/null @@ -1,106 +0,0 @@ -removeSymfonyInternalServices($containerBuilder); - $this->removeTemporaryAnonymousIds($containerBuilder); - - foreach ($containerBuilder->getDefinitions() as $definition) { - $this->resolvePolyfillForNameTag($definition); - } - } - - private function removeSymfonyInternalServices(ContainerBuilder $containerBuilder): void - { - $containerBuilder->removeDefinition('service_container'); - $containerBuilder->removeAlias(PsrContainerInterface::class); - $containerBuilder->removeAlias(ContainerInterface::class); - } - - private function removeTemporaryAnonymousIds(ContainerBuilder $containerBuilder): void - { - $definitions = $this->privatesAccessor->getPrivateProperty($containerBuilder, 'definitions'); - - foreach ($definitions as $name => $definition) { - if (! is_string($name)) { - continue; - } - - if (! $this->isGeneratedKeyForAnonymousClass($name)) { - continue; - } - - unset($definitions[$name]); - $definitions[] = $definition; - } - - $this->privatesAccessor->setPrivateProperty($containerBuilder, 'definitions', $definitions); - } - - private function isGeneratedKeyForAnonymousClass(string $name): bool - { - return (bool) Strings::match($name, self::ANONYMOUS_CLASS_REGEX); - } - - private function resolvePolyfillForNameTag(Definition $definition): void - { - if ($definition->getTags() === []) { - return; - } - - $tags = $definition->getTags(); - foreach ($definition->getTags() as $name => $value) { - /** @var mixed[] $tagValues */ - $tagValues = $value[0]; - if ($this->shouldSkipNameTagInlining($tagValues)) { - continue; - } - - unset($tags[$name]); - - $tagValues = []; - foreach ($value as $singleValue) { - $singleTag = array_merge([ - 'name' => $name, - ], $singleValue); - $tagValues[] = $singleTag; - } - - $tags[] = $tagValues; - } - - $definition->setTags($tags); - } - - /** - * @param array $tagValues - */ - private function shouldSkipNameTagInlining(array $tagValues): bool - { - return $tagValues === []; - } -} diff --git a/src/DependencyInjection/Loader/IdAwareXmlFileLoader.php b/src/DependencyInjection/Loader/IdAwareXmlFileLoader.php deleted file mode 100644 index 341c43f42f2..00000000000 --- a/src/DependencyInjection/Loader/IdAwareXmlFileLoader.php +++ /dev/null @@ -1,242 +0,0 @@ -privatesCaller = new PrivatesCaller(); - } - - /** - * @param string|string[]|null $exclude - */ - public function import( - mixed $resource, - string $type = null, - bool|string $ignoreErrors = false, - string $sourceResource = null, - $exclude = null - ): mixed { - $this->xmlImportCollector->addImport($resource, $ignoreErrors); - return null; - } - - public function load(mixed $resource, ?string $type = null): mixed - { - $path = $this->locator->locate($resource); - - if (! is_string($path)) { - throw new XmlParsingException(); - } - - // mostly mimics parseFileToDOM(), just without validation, that often breaks due to missing extension - $domDocument = $this->parseFileToDOMWithoutValidation($path); - - // file not found - if (! $this->container->fileExists($path)) { - return null; - } - - $defaults = $this->privatesCaller->callPrivateMethod($this, 'getServiceDefaults', [$domDocument, $path]); - $this->processAnonymousServices($domDocument, $path); - - // imports - $this->privatesCaller->callPrivateMethod($this, 'parseImports', [$domDocument, $path]); - - // parameters - $this->privatesCaller->callPrivateMethod($this, 'parseParameters', [$domDocument, $path]); - - // faking extensions - $aliasAndNamespaceConfigurableExtension = new AliasAndNamespaceConfigurableExtension( - 'doctrine', - 'http://symfony.com/schema/dic/doctrine' - ); - $this->container->registerExtension($aliasAndNamespaceConfigurableExtension); - - $this->privatesCaller->callPrivateMethod($this, 'loadFromExtensions', [$domDocument]); - - // services - try { - $this->privatesCaller->callPrivateMethod($this, 'parseDefinitions', [$domDocument, $path, $defaults]); - } finally { - $this->instanceof = []; - $this->registerAliasesForSinglyImplementedInterfaces(); - } - - return null; - } - - private function processAnonymousServices(DOMDocument $domDocument, string $file): void - { - $this->count = 0; - - /** @var array $definitions */ - $definitions = []; - - $domxPath = new DOMXPath($domDocument); - $domxPath->registerNamespace('container', self::NS); - - $definitions = $this->processAnonymousServicesInArguments($domxPath, $file, $definitions); - - /** @var DOMNodeList $nodeWithIds */ - $nodeWithIds = $domxPath->query('//container:services/container:service[@id]'); - $hasNamedServices = (bool) $nodeWithIds->length; - - // anonymous services "in the wild" - $anonymousServiceNodes = $domxPath->query('//container:services/container:service[not(@id)]'); - if ($anonymousServiceNodes instanceof DOMNodeList) { - foreach ($anonymousServiceNodes as $anonymouServiceNode) { - /** @var DOMElement $anonymouServiceNode */ - $id = $this->createAnonymousServiceId($hasNamedServices, $anonymouServiceNode, $file); - $anonymouServiceNode->setAttribute(self::ID, $id); - $definitions[$id] = [$anonymouServiceNode, $file, true]; - } - } - - // resolve definitions - uksort($definitions, 'strnatcmp'); - - $inversedDefinitions = array_reverse($definitions); - foreach ($inversedDefinitions as $id => [$domElement, $file]) { - $definition = $this->privatesCaller->callPrivateMethod( - $this, - 'parseDefinition', - [$domElement, $file, new Definition()] - ); - - if ($definition !== null) { - $this->setDefinition($id, $definition); - } - } - } - - /** - * @return mixed[] - * @param mixed[] $definitions - */ - private function processAnonymousServicesInArguments( - DOMXPath $domxPath, - string $file, - array $definitions - ): array { - $nodes = $domxPath->query( - '//container:argument[@type="service"][not(@id)]|//container:property[@type="service"][not(@id)]|//container:bind[not(@id)]|//container:factory[not(@service)]|//container:configurator[not(@service)]' - ); - - if ($nodes !== false) { - /** @var DOMElement $node */ - foreach ($nodes as $node) { - // get current service id - - $parentNode = $node->parentNode; - assert($parentNode instanceof DOMElement); - - // @see https://stackoverflow.com/a/28944/1348344 - $parentServiceId = $parentNode->getAttribute('id'); - - /** @var DOMElement[] $services */ - $services = $this->privatesCaller->callPrivateMethod($this, 'getChildren', [$node, 'service']); - if ($services !== []) { - $id = $this->createUniqueServiceNameFromClass($services[0], $parentServiceId); - - $node->setAttribute(self::ID, $id); - $node->setAttribute('service', $id); - - $definitions[$id] = [$services[0], $file]; - $services[0]->setAttribute(self::ID, $id); - - // anonymous services are always private - // we could not use the constant false here, because of XML parsing - $services[0]->setAttribute('public', 'false'); - } - } - } - - return $definitions; - } - - private function createUniqueServiceNameFromClass(DOMElement $serviceDomElement, string $parentServiceId): string - { - $class = $serviceDomElement->getAttribute('class'); - $serviceName = $parentServiceId . '.' . $this->createServiceNameFromClass($class); - - return $this->uniqueNaming->uniquateName($serviceName); - } - - private function createServiceNameFromClass(string $class): string - { - $serviceName = Strings::replace($class, '#\\\\#', '.'); - $serviceName = strtolower($serviceName); - - return $this->uniqueNaming->uniquateName($serviceName); - } - - private function createAnonymousServiceId(bool $hasNamedServices, DOMElement $domElement, string $file): string - { - $className = $domElement->getAttribute('class'); - if ($hasNamedServices) { - return $this->createServiceNameFromClass($className); - } - - $hashedFileName = hash('sha256', $file); - return sprintf('%d_%s', ++$this->count, $hashedFileName); - } - - private function parseFileToDOMWithoutValidation(string $path): DOMDocument - { - try { - return XmlUtils::loadFile($path); - } catch (InvalidArgumentException $invalidArgumentException) { - $errorMessage = sprintf('Unable to parse file "%s": %s', $path, $invalidArgumentException->getMessage()); - - throw new XmlParsingException( - $errorMessage, - $invalidArgumentException->getCode(), - $invalidArgumentException - ); - } - } -} diff --git a/src/DependencyInjection/Loader/MissingAutodiscoveryDirectoryTolerantYamlFileLoader.php b/src/DependencyInjection/Loader/MissingAutodiscoveryDirectoryTolerantYamlFileLoader.php index 33a0d864f14..ff9dab0aab2 100644 --- a/src/DependencyInjection/Loader/MissingAutodiscoveryDirectoryTolerantYamlFileLoader.php +++ b/src/DependencyInjection/Loader/MissingAutodiscoveryDirectoryTolerantYamlFileLoader.php @@ -15,6 +15,6 @@ public function registerClasses( string $resource, string|array $exclude = null ): void { - // skip laoding classes, as the resource might not exist and invoke autoloading + // skip loading classes, as the resource might not exist and invoke autoloading } } diff --git a/src/DependencyInjection/LoaderFactory/IdAwareXmlFileLoaderFactory.php b/src/DependencyInjection/LoaderFactory/IdAwareXmlFileLoaderFactory.php deleted file mode 100644 index b60c6be6b1c..00000000000 --- a/src/DependencyInjection/LoaderFactory/IdAwareXmlFileLoaderFactory.php +++ /dev/null @@ -1,30 +0,0 @@ -uniqueNaming, - $this->xmlImportCollector - ); - } -} diff --git a/src/Enum/Format.php b/src/Enum/Format.php index f9878e01302..bf31d5003d4 100644 --- a/src/Enum/Format.php +++ b/src/Enum/Format.php @@ -16,11 +16,6 @@ final class Format */ public const YML = 'yml'; - /** - * @var string - */ - public const XML = 'xml'; - /** * @var string */ diff --git a/src/FileSystem/ConfigFileDumper.php b/src/FileSystem/ConfigFileDumper.php index 6778aeb5098..e44b11856ec 100644 --- a/src/FileSystem/ConfigFileDumper.php +++ b/src/FileSystem/ConfigFileDumper.php @@ -4,17 +4,16 @@ namespace Symplify\ConfigTransformer\FileSystem; +use Nette\Utils\FileSystem; use Symfony\Component\Console\Style\SymfonyStyle; +use Symplify\ConfigTransformer\Console\ConsoleDiffer; use Symplify\ConfigTransformer\ValueObject\Configuration; use Symplify\ConfigTransformer\ValueObject\ConvertedContent; -use Symplify\PackageBuilder\Console\Output\ConsoleDiffer; -use Symplify\SmartFileSystem\SmartFileSystem; final class ConfigFileDumper { public function __construct( private readonly SymfonyStyle $symfonyStyle, - private readonly SmartFileSystem $smartFileSystem, private readonly ConsoleDiffer $consoleDiffer ) { } @@ -52,6 +51,6 @@ public function dumpFile(ConvertedContent $convertedContent, Configuration $conf $this->symfonyStyle->title($fileTitle); - $this->smartFileSystem->dumpFile($newFileRealPath, $convertedContent->getConvertedContent()); + FileSystem::write($newFileRealPath, $convertedContent->getConvertedContent()); } } diff --git a/src/FileSystem/RelativeFilePathHelper.php b/src/FileSystem/RelativeFilePathHelper.php new file mode 100644 index 00000000000..f9a4169abd8 --- /dev/null +++ b/src/FileSystem/RelativeFilePathHelper.php @@ -0,0 +1,32 @@ +makePathRelative( + $normalizedFilePath, + (string) realpath($directory) + ); + + return rtrim($relativeFilePath, '/'); + } + + private static function normalizePath(string $path): string + { + return str_replace('\\', '/', $path); + } +} diff --git a/src/Finder/ConfigFileFinder.php b/src/Finder/ConfigFileFinder.php index b41e7936925..c7b12d263f1 100644 --- a/src/Finder/ConfigFileFinder.php +++ b/src/Finder/ConfigFileFinder.php @@ -4,9 +4,8 @@ namespace Symplify\ConfigTransformer\Finder; -use Symplify\ConfigTransformer\ValueObject\Configuration; -use Symplify\SmartFileSystem\Finder\SmartFinder; -use Symplify\SmartFileSystem\SmartFileInfo; +use Symfony\Component\Finder\Finder; +use Symfony\Component\Finder\SplFileInfo; final class ConfigFileFinder { @@ -16,16 +15,17 @@ final class ConfigFileFinder */ private const CONFIG_SUFFIXES_REGEX = '#\.(yml|yaml|xml)$#'; - public function __construct( - private readonly SmartFinder $smartFinder - ) { - } - /** - * @return SmartFileInfo[] + * @param string[] $sources + * @return SplFileInfo[] */ - public function findFileInfos(Configuration $configuration): array + public function findFileInfos(array $sources): array { - return $this->smartFinder->find($configuration->getSources(), self::CONFIG_SUFFIXES_REGEX); + $finder = new Finder(); + $finder->files() + ->in($sources) + ->name(self::CONFIG_SUFFIXES_REGEX); + + return iterator_to_array($finder->getIterator()); } } diff --git a/src/Kernel/ConfigTransformerKernel.php b/src/Kernel/ConfigTransformerKernel.php index 0695b463002..86db0ed3d0f 100644 --- a/src/Kernel/ConfigTransformerKernel.php +++ b/src/Kernel/ConfigTransformerKernel.php @@ -4,20 +4,28 @@ namespace Symplify\ConfigTransformer\Kernel; -use Psr\Container\ContainerInterface; +use Symfony\Component\Config\Loader\LoaderInterface; +use Symfony\Component\HttpKernel\Kernel; use Symplify\PhpConfigPrinter\ValueObject\PhpConfigPrinterConfig; -use Symplify\SymplifyKernel\HttpKernel\AbstractSymplifyKernel; -final class ConfigTransformerKernel extends AbstractSymplifyKernel +/** + * @api used in tests and bin + */ +final class ConfigTransformerKernel extends Kernel { - /** - * @param string[] $configFiles - */ - public function createFromConfigs(array $configFiles): ContainerInterface + public function __construct() { - $configFiles[] = __DIR__ . '/../../config/config.php'; - $configFiles[] = PhpConfigPrinterConfig::FILE_PATH; + parent::__construct('dev', true); + } - return $this->create($configFiles); + public function registerBundles(): iterable + { + return []; + } + + public function registerContainerConfiguration(LoaderInterface $loader): void + { + $loader->load(__DIR__ . '/../../config/config.php'); + $loader->load(PhpConfigPrinterConfig::FILE_PATH); } } diff --git a/src/Naming/UniqueNaming.php b/src/Naming/UniqueNaming.php deleted file mode 100644 index 8027793cbd1..00000000000 --- a/src/Naming/UniqueNaming.php +++ /dev/null @@ -1,26 +0,0 @@ - - */ - private array $existingNames = []; - - public function uniquateName(string $name): string - { - if (isset($this->existingNames[$name])) { - $serviceNameCounter = $this->existingNames[$name]; - $this->existingNames[$name] = ++$serviceNameCounter; - return $name . '.' . $serviceNameCounter; - } - - $this->existingNames[$name] = 1; - - return $name; - } -} diff --git a/src/Reflection/PrivatesAccessor.php b/src/Reflection/PrivatesAccessor.php new file mode 100644 index 00000000000..49a9287d904 --- /dev/null +++ b/src/Reflection/PrivatesAccessor.php @@ -0,0 +1,28 @@ +setAccessible(true); + + return $reflectionProperty->getValue($object); + } + + // write private property + public static function writePrivateProperty(object $object, string $propertyName, mixed $value): void + { + $reflectionProperty = new ReflectionProperty($object, $propertyName); + $reflectionProperty->setAccessible(true); + + $reflectionProperty->setValue($object, $value); + } +} diff --git a/src/ValueObject/ConvertedContent.php b/src/ValueObject/ConvertedContent.php index a59965c16e2..64562754212 100644 --- a/src/ValueObject/ConvertedContent.php +++ b/src/ValueObject/ConvertedContent.php @@ -5,13 +5,20 @@ namespace Symplify\ConfigTransformer\ValueObject; use Nette\Utils\Strings; -use Symplify\SmartFileSystem\SmartFileInfo; +use Symfony\Component\Finder\SplFileInfo; +use Symplify\ConfigTransformer\FileSystem\RelativeFilePathHelper; final class ConvertedContent { + /** + * @var string + * @see https://regex101.com/r/SYP00O/1 + */ + private const LAST_SUFFIX_REGEX = '#\.[^.]+$#'; + public function __construct( private readonly string $convertedContent, - private readonly SmartFileInfo $originalFileInfo + private readonly SplFileInfo $originalFileInfo ) { } @@ -30,12 +37,12 @@ public function getNewRelativeFilePath(): string public function getOriginalFilePathWithoutSuffix(): string { - return $this->originalFileInfo->getRealPathWithoutSuffix(); + return Strings::replace($this->originalFileInfo->getRealPath(), self::LAST_SUFFIX_REGEX, ''); } public function getOriginalRelativeFilePath(): string { - return $this->originalFileInfo->getRelativeFilePathFromCwd(); + return RelativeFilePathHelper::resolveFromDirectory($this->originalFileInfo->getRealPath(), getcwd()); } public function getOriginalContent(): string diff --git a/src/ValueObject/DependencyInjection/Extension/AliasAndNamespaceConfigurableExtension.php b/src/ValueObject/DependencyInjection/Extension/AliasAndNamespaceConfigurableExtension.php deleted file mode 100644 index c24e09cf844..00000000000 --- a/src/ValueObject/DependencyInjection/Extension/AliasAndNamespaceConfigurableExtension.php +++ /dev/null @@ -1,34 +0,0 @@ -alias; - } - - public function getNamespace(): string - { - return $this->namespace; - } - - /** - * @param string[] $configs - */ - public function load(array $configs, ContainerBuilder $containerBuilder): void - { - } -} diff --git a/tests/AbstractTestCase.php b/tests/AbstractTestCase.php new file mode 100644 index 00000000000..5f1fff7407c --- /dev/null +++ b/tests/AbstractTestCase.php @@ -0,0 +1,33 @@ +boot(); + + $this->container = $configTransformerKernel->getContainer(); + } + + /** + * @template T as object + * + * @param class-string $type + * @return T + */ + protected function getService(string $type): object + { + return $this->container->get($type); + } +} diff --git a/tests/Converter/ConfigFormatConverter/AbstractConfigFormatConverterTestCase.php b/tests/Converter/ConfigFormatConverter/AbstractConfigFormatConverterTestCase.php deleted file mode 100644 index b8a2783548a..00000000000 --- a/tests/Converter/ConfigFormatConverter/AbstractConfigFormatConverterTestCase.php +++ /dev/null @@ -1,40 +0,0 @@ -bootKernel(ConfigTransformerKernel::class); - $this->configFormatConverter = $this->getService(ConfigFormatConverter::class); - $this->smartFileSystem = $this->getService(SmartFileSystem::class); - } - - protected function doTestOutput(SmartFileInfo $fixtureFileInfo, bool $preserveDirStructure = false): void - { - $inputAndExpected = StaticFixtureSplitter::splitFileInfoToLocalInputAndExpectedFileInfos($fixtureFileInfo, false, $preserveDirStructure); - $this->doTestFileInfo($inputAndExpected->getInputFileInfo(), $inputAndExpected->getExpectedFileContent(), $fixtureFileInfo); - } - - protected function doTestFileInfo(SmartFileInfo $inputFileInfo, string $expectedContent, SmartFileInfo $fixtureFileInfo): void - { - $convertedContent = $this->configFormatConverter->convert($inputFileInfo); - StaticFixtureUpdater::updateFixtureContent($inputFileInfo, $convertedContent, $fixtureFileInfo); - $this->assertSame($expectedContent, $convertedContent, $fixtureFileInfo->getRelativeFilePathFromCwd()); - } -} diff --git a/tests/Converter/ConfigFormatConverter/XmlToPhp/Fixture/doctrine_config.xml b/tests/Converter/ConfigFormatConverter/XmlToPhp/Fixture/doctrine_config.xml deleted file mode 100644 index 9dee458fa04..00000000000 --- a/tests/Converter/ConfigFormatConverter/XmlToPhp/Fixture/doctrine_config.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - ------ -extension('doctrine', [ - 'dbal' => [ - 'url' => '%env(resolve:DATABASE_URL)%', - ], - ]); -}; diff --git a/tests/Converter/ConfigFormatConverter/XmlToPhp/Fixture/multiple_tags.xml b/tests/Converter/ConfigFormatConverter/XmlToPhp/Fixture/multiple_tags.xml deleted file mode 100644 index bb6e8a474e0..00000000000 --- a/tests/Converter/ConfigFormatConverter/XmlToPhp/Fixture/multiple_tags.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - ------ -services(); - - $services->set('mime_types') - ->tag('tag1') - ->tag('tag2'); -}; diff --git a/tests/Converter/ConfigFormatConverter/XmlToPhp/Fixture/no_import_inling.xml b/tests/Converter/ConfigFormatConverter/XmlToPhp/Fixture/no_import_inling.xml deleted file mode 100644 index 8343da9033e..00000000000 --- a/tests/Converter/ConfigFormatConverter/XmlToPhp/Fixture/no_import_inling.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - ------ -import(__DIR__ . '/some.php'); -}; diff --git a/tests/Converter/ConfigFormatConverter/XmlToPhp/Fixture/single_service_tag.xml b/tests/Converter/ConfigFormatConverter/XmlToPhp/Fixture/single_service_tag.xml deleted file mode 100644 index f7286775ae1..00000000000 --- a/tests/Converter/ConfigFormatConverter/XmlToPhp/Fixture/single_service_tag.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - ------ -services(); - - $services->set('mime_types') - ->tag('controller.service_subscriber') - ->tag('controller.service_arguments'); -}; diff --git a/tests/Converter/ConfigFormatConverter/XmlToPhp/Fixture/some.xml b/tests/Converter/ConfigFormatConverter/XmlToPhp/Fixture/some.xml deleted file mode 100644 index 9f50aca3ce9..00000000000 --- a/tests/Converter/ConfigFormatConverter/XmlToPhp/Fixture/some.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - 10000 - - - - ------ -services(); - - $services->set('mime_types', MimeTypes::class) - ->args([ - '', - ]) - ->call('setDefault', [ - service('mime_types'), - ]) - ->call('setExtra', [ - '10000', - ]); -}; diff --git a/tests/Converter/ConfigFormatConverter/XmlToPhp/Fixture/tag_with_additional_attributes.xml b/tests/Converter/ConfigFormatConverter/XmlToPhp/Fixture/tag_with_additional_attributes.xml deleted file mode 100644 index 092f3ab14df..00000000000 --- a/tests/Converter/ConfigFormatConverter/XmlToPhp/Fixture/tag_with_additional_attributes.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - ------ -services(); - - $services->set('mime_types') - ->tag('tag1', [ - 'priority' => 1, - ]) - ->tag('tag2', [ - 'priority' => 2, - ]); -}; diff --git a/tests/Converter/ConfigFormatConverter/XmlToPhp/Source/some.xml b/tests/Converter/ConfigFormatConverter/XmlToPhp/Source/some.xml deleted file mode 100644 index c14e4eaf2c4..00000000000 --- a/tests/Converter/ConfigFormatConverter/XmlToPhp/Source/some.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - 10000 - - - - diff --git a/tests/Converter/ConfigFormatConverter/XmlToPhp/XmlToPhpTest.php b/tests/Converter/ConfigFormatConverter/XmlToPhp/XmlToPhpTest.php deleted file mode 100644 index 6eabe2c06dc..00000000000 --- a/tests/Converter/ConfigFormatConverter/XmlToPhp/XmlToPhpTest.php +++ /dev/null @@ -1,33 +0,0 @@ -smartFileSystem->copy( - __DIR__ . '/Source/some.xml', - sys_get_temp_dir() . '/_temp_fixture_easy_testing/some.xml' - ); - - $this->doTestOutput($fixtureFileInfo); - } - - /** - * @return Iterator - */ - public static function provideData(): Iterator - { - return StaticFixtureFinder::yieldDirectory(__DIR__ . '/Fixture', '*.xml'); - } -} diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/nested/some_config/defaults.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/nested/some_config/defaults.yaml deleted file mode 100644 index 29bf612f151..00000000000 --- a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/nested/some_config/defaults.yaml +++ /dev/null @@ -1,27 +0,0 @@ -services: - _defaults: - autowire: true - public: true - - Symfony\Component\Filesystem\Filesystem: null - Symplify\SmartFileSystem\Finder\FinderSanitizer: null ------ -services(); - - $services->defaults() - ->autowire() - ->public(); - - $services->set(Filesystem::class); - - $services->set(FinderSanitizer::class); -}; diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/nested/some_config/exclude.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/nested/some_config/exclude.yaml deleted file mode 100644 index 7284ee0a44e..00000000000 --- a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/nested/some_config/exclude.yaml +++ /dev/null @@ -1,30 +0,0 @@ -services: - _defaults: - autowire: true - public: true - - Symplify\Autodiscovery\: - resource: '../src' - exclude: - - '../src/HttpKernel/*' - - '../src/That/*' ------ -services(); - - $services->defaults() - ->autowire() - ->public(); - - $services->load('Symplify\Autodiscovery\\', __DIR__ . '/../src') - ->exclude([ - __DIR__ . '/../src/HttpKernel/*', - __DIR__ . '/../src/That/*', - ]); -}; diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/nested/some_config/import_me.yml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/nested/some_config/import_me.yml deleted file mode 100644 index 42946fd6307..00000000000 --- a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/nested/some_config/import_me.yml +++ /dev/null @@ -1,2 +0,0 @@ -parameters: - key: value diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/nested/some_config/imports.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/nested/some_config/imports.yaml deleted file mode 100644 index 02dc5b1363d..00000000000 --- a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/nested/some_config/imports.yaml +++ /dev/null @@ -1,12 +0,0 @@ -imports: - - { resource: 'import_me.yml' } ------ -import(__DIR__ . '/import_me.php'); -}; diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/nested/src/SomeClass.php b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/nested/src/SomeClass.php deleted file mode 100644 index 5a2960cd0db..00000000000 --- a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/nested/src/SomeClass.php +++ /dev/null @@ -1,9 +0,0 @@ -extension('hautelook_alice', [ - 'fixtures_path' => 'fixtures', - ]); -}; diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/parameters.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/parameters.yaml similarity index 100% rename from tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/parameters.yaml rename to tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/parameters.yaml diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/reference.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/reference.yaml similarity index 100% rename from tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/reference.yaml rename to tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/reference.yaml diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/resource_arguments_and_bind.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/resource_arguments_and_bind.yaml similarity index 100% rename from tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/resource_arguments_and_bind.yaml rename to tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/resource_arguments_and_bind.yaml diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_alias.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_alias.yaml similarity index 100% rename from tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_alias.yaml rename to tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_alias.yaml diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_arguments.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_arguments.yaml similarity index 100% rename from tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_arguments.yaml rename to tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_arguments.yaml diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_calls.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_calls.yaml similarity index 100% rename from tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_calls.yaml rename to tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_calls.yaml diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_configurator.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_configurator.yaml similarity index 100% rename from tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_configurator.yaml rename to tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_configurator.yaml diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_decoration.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_decoration.yaml similarity index 100% rename from tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_decoration.yaml rename to tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_decoration.yaml diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_deprecation.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_deprecation.yaml similarity index 100% rename from tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_deprecation.yaml rename to tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_deprecation.yaml diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_factory.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_factory.yaml similarity index 100% rename from tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_factory.yaml rename to tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_factory.yaml diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_imports.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_imports.yaml similarity index 100% rename from tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_imports.yaml rename to tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_imports.yaml diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_lazy.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_lazy.yaml similarity index 100% rename from tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_lazy.yaml rename to tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_lazy.yaml diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_load_resources_simple.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_load_resources_simple.yaml similarity index 100% rename from tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_load_resources_simple.yaml rename to tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_load_resources_simple.yaml diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_null_value.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_null_value.yaml similarity index 100% rename from tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_null_value.yaml rename to tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_null_value.yaml diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_parent.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_parent.yaml similarity index 100% rename from tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_parent.yaml rename to tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_parent.yaml diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_shared.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_shared.yaml similarity index 100% rename from tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_shared.yaml rename to tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_shared.yaml diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_tags.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_tags.yaml similarity index 100% rename from tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/maker-bundle/services_tags.yaml rename to tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_tags.yaml diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_test.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_test.yaml deleted file mode 100644 index c44d85186fc..00000000000 --- a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/normal/services_test.yaml +++ /dev/null @@ -1,23 +0,0 @@ -services: - _defaults: - autowire: true - autoconfigure: true - - App\Tests\Behat\: - resource: 'tests/Behat/*' ------ -services(); - - $services->defaults() - ->autowire() - ->autoconfigure(); - - $services->load('App\Tests\Behat\\', __DIR__ . '/tests/Behat/*'); -}; diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/routing/requirement_d_param.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/routing/requirement_d_param.yaml index 22f293d9e2e..6d20abd2df3 100644 --- a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/routing/requirement_d_param.yaml +++ b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/routing/requirement_d_param.yaml @@ -15,6 +15,6 @@ return static function (RoutingConfigurator $routingConfigurator): void { $routingConfigurator->add('site_root', '/{siteId}') ->controller('AppBundle\Controller\Site\IndexController') ->requirements([ - 'siteId' => '\d+', + 'siteId' => 'd+', ]); }; diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/routing/routes.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/routing/routes.yaml index c941ceb0f56..b3ba716d8d5 100644 --- a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/routing/routes.yaml +++ b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/routing/routes.yaml @@ -12,12 +12,11 @@ research_thank_you: declare(strict_types=1); -use Symfony\Bundle\FrameworkBundle\Controller\TemplateController; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; return static function (RoutingConfigurator $routingConfigurator): void { $routingConfigurator->add('research_thank_you', 'research/thank-you') - ->controller(TemplateController::class) + ->controller('Symfony\Bundle\FrameworkBundle\Controller\TemplateController') ->defaults([ 'template' => 'research/thank-you.twig', ]) diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/routing/routes_with_defaults_controller.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/routing/routes_with_defaults_controller.yaml index b162dc59569..bdce8085c23 100644 --- a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/routing/routes_with_defaults_controller.yaml +++ b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/routing/routes_with_defaults_controller.yaml @@ -9,12 +9,11 @@ research_thank_you: declare(strict_types=1); -use Symfony\Bundle\FrameworkBundle\Controller\TemplateController; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; return static function (RoutingConfigurator $routingConfigurator): void { $routingConfigurator->add('research_thank_you', 'research/thank-you') - ->controller(TemplateController::class) + ->controller('Symfony\Bundle\FrameworkBundle\Controller\TemplateController') ->defaults([ 'template' => 'research/thank-you.twig', ]); diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/routing/with_host.yaml b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/routing/with_host.yaml index 377781c6e3d..932ec7bef0c 100644 --- a/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/routing/with_host.yaml +++ b/tests/Converter/ConfigFormatConverter/YamlToPhp/Fixture/routing/with_host.yaml @@ -7,11 +7,10 @@ with_host: declare(strict_types=1); -use Symfony\Bundle\FrameworkBundle\Controller\TemplateController; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; return static function (RoutingConfigurator $routingConfigurator): void { $routingConfigurator->add('with_host', 'research/thank-you') ->host('getrector.com') - ->controller(TemplateController::class); + ->controller('Symfony\Bundle\FrameworkBundle\Controller\TemplateController'); }; diff --git a/tests/Converter/ConfigFormatConverter/YamlToPhp/YamlToPhpTest.php b/tests/Converter/ConfigFormatConverter/YamlToPhp/YamlToPhpTest.php index 25647ede2e4..42210f299b5 100644 --- a/tests/Converter/ConfigFormatConverter/YamlToPhp/YamlToPhpTest.php +++ b/tests/Converter/ConfigFormatConverter/YamlToPhp/YamlToPhpTest.php @@ -7,34 +7,44 @@ use Iterator; use Nette\Utils\FileSystem; use PHPUnit\Framework\Attributes\DataProvider; -use Symplify\ConfigTransformer\Tests\Converter\ConfigFormatConverter\AbstractConfigFormatConverterTestCase; -use Symplify\EasyTesting\DataProvider\StaticFixtureFinder; -use Symplify\EasyTesting\StaticFixtureSplitter; -use Symplify\SmartFileSystem\SmartFileInfo; - -final class YamlToPhpTest extends AbstractConfigFormatConverterTestCase +use Symfony\Component\Finder\SplFileInfo; +use Symplify\ConfigTransformer\Converter\ConfigFormatConverter; +use Symplify\ConfigTransformer\FileSystem\RelativeFilePathHelper; +use Symplify\ConfigTransformer\Tests\AbstractTestCase; +use Symplify\ConfigTransformer\Tests\Helper\FixtureFinder; +use Symplify\ConfigTransformer\Tests\Helper\FixtureSplitter; +use Symplify\ConfigTransformer\Tests\Helper\FixtureUpdater; + +final class YamlToPhpTest extends AbstractTestCase { + private ConfigFormatConverter $configFormatConverter; + + protected function setUp(): void + { + parent::setUp(); + $this->configFormatConverter = $this->getService(ConfigFormatConverter::class); + } + #[DataProvider('provideDataForRouting')] - public function testRouting(SmartFileInfo $fileInfo): void + public function testRouting(SplFileInfo $fileInfo): void { $this->doTestOutput($fileInfo, true); } - /** - * @return Iterator - */ public static function provideDataForRouting(): Iterator { - return StaticFixtureFinder::yieldDirectory(__DIR__ . '/Fixture/routing', '*.yaml'); + return FixtureFinder::yieldDirectory(__DIR__ . '/Fixture/routing', '*.yaml'); } #[DataProvider('provideData')] #[DataProvider('provideDataWithPhpImported')] - public function testNormal(SmartFileInfo $fixtureFileInfo): void + public function testNormal(SplFileInfo $fixtureFileInfo): void { // for imports - $temporaryPath = StaticFixtureSplitter::getTemporaryPath(); - $this->smartFileSystem->mirror(__DIR__ . '/Fixture/normal', $temporaryPath); + $temporaryPath = FixtureSplitter::getTemporaryPath(); + + $filesystem = new \Symfony\Component\Filesystem\Filesystem(); + $filesystem->mirror(__DIR__ . '/Fixture/normal', $temporaryPath); // for the "resource: items/" FileSystem::createDir($temporaryPath . '/items'); @@ -53,103 +63,30 @@ public function testNormal(SmartFileInfo $fixtureFileInfo): void $temporaryPath . '/directory-with-unquoted-strings' ); - $this->doTestOutput($fixtureFileInfo); - } - - #[DataProvider('provideDataWithDirectory')] - public function testSpecialCaseWithDirectory(SmartFileInfo $fileInfo): void - { - $this->doTestOutputWithExtraDirectory($fileInfo, __DIR__ . '/Fixture/nested'); - } - - #[DataProvider('provideDataExtension')] - public function testEcs(SmartFileInfo $fileInfo): void - { - $this->doTestOutputWithExtraDirectory($fileInfo, $fileInfo->getPath()); + $this->doTestOutput($fixtureFileInfo, false); } - /** - * @source https://github.com/symfony/maker-bundle/pull/604 - */ - #[DataProvider('provideDataMakerBundle')] - public function testMakerBundle(SmartFileInfo $fileInfo): void - { - // needed for all the included - $temporaryPath = StaticFixtureSplitter::getTemporaryPath(); - $this->smartFileSystem->dumpFile( - $temporaryPath . '/../src/SomeClass.php', - 'smartFileSystem->mkdir($temporaryPath . '/../src/Controller'); - $this->smartFileSystem->mkdir($temporaryPath . '/../src/Domain'); - - $this->doTestOutput($fileInfo); - } - - /** - * @return Iterator - */ public static function provideData(): Iterator { - return StaticFixtureFinder::yieldDirectory(__DIR__ . '/Fixture/normal', '*.yaml'); + return FixtureFinder::yieldDirectory(__DIR__ . '/Fixture/normal', '*.yaml'); } - /** - * @return Iterator - */ public static function provideDataWithPhpImported(): Iterator { - return StaticFixtureFinder::yieldDirectory(__DIR__ . '/Fixture/skip-imported-php', '*.yaml'); - } - - /** - * @return Iterator - */ - public static function provideDataExtension(): Iterator - { - return StaticFixtureFinder::yieldDirectory(__DIR__ . '/Fixture/extension', '*.yaml'); - } - - /** - * @return Iterator - */ - public static function provideDataWithDirectory(): Iterator - { - return StaticFixtureFinder::yieldDirectory(__DIR__ . '/Fixture/nested', '*.yaml'); + return FixtureFinder::yieldDirectory(__DIR__ . '/Fixture/skip-imported-php', '*.yaml'); } - /** - * @return Iterator - */ - public static function provideDataMakerBundle(): Iterator + private function doTestOutput(SplFileInfo $fixtureFileInfo, bool $preserveDirStructure = false): void { - return StaticFixtureFinder::yieldDirectory(__DIR__ . '/Fixture/maker-bundle', '*.yaml'); - } - - private function doTestOutputWithExtraDirectory(SmartFileInfo $fixtureFileInfo, string $extraDirectory): void - { - $inputAndExpected = StaticFixtureSplitter::splitFileInfoToInputAndExpected($fixtureFileInfo); - - $temporaryPath = StaticFixtureSplitter::getTemporaryPath(); - - // copy /src to temp directory, so Symfony FileLocator knows about it - $this->smartFileSystem->mirror($extraDirectory, $temporaryPath, null, [ - 'override' => true, - ]); - - $fileTemporaryPath = $temporaryPath . '/' . $fixtureFileInfo->getRelativeFilePathFromDirectory($extraDirectory); - $this->smartFileSystem->dumpFile($fileTemporaryPath, $inputAndExpected->getInput()); - - // require class to autoload it - $expectedFilePath = $temporaryPath . '/src/SomeClass.php'; - $this->assertFileExists($expectedFilePath); + $inputAndExpected = FixtureSplitter::splitFileInfoToLocalInputAndExpectedFileInfos($fixtureFileInfo, false, $preserveDirStructure); - require_once $expectedFilePath; + $inputFileInfo = $inputAndExpected->getInputFileInfo(); + $convertedContent = $this->configFormatConverter->convert($inputFileInfo); - $inputFileInfo = new SmartFileInfo($fileTemporaryPath); + // run `UT=1 vendor/bin/phpunit` to update test fixtures content + FixtureUpdater::updateFixtureContent($inputFileInfo, $convertedContent, $fixtureFileInfo); - $this->doTestFileInfo($inputFileInfo, $inputAndExpected->getExpected(), $fixtureFileInfo); + $filePath = RelativeFilePathHelper::resolveFromDirectory($fixtureFileInfo->getRealPath(), getcwd()); + $this->assertSame($inputAndExpected->getExpectedFileContent(), $convertedContent, $filePath); } } diff --git a/tests/Converter/YamlToPhpConverter/Fixture/expected_parameters.php b/tests/Converter/YamlToPhpConverter/Fixture/expected_parameters.php index 4cc3ec4a8db..d395f50d367 100644 --- a/tests/Converter/YamlToPhpConverter/Fixture/expected_parameters.php +++ b/tests/Converter/YamlToPhpConverter/Fixture/expected_parameters.php @@ -8,4 +8,6 @@ $parameters = $containerConfigurator->parameters(); $parameters->set('key', 'value'); + + $parameters->set('format', 'd+'); }; diff --git a/tests/Converter/YamlToPhpConverter/YamlToPhpConverterTest.php b/tests/Converter/YamlToPhpConverter/YamlToPhpConverterTest.php index 175770bd5d2..1c01d662b48 100644 --- a/tests/Converter/YamlToPhpConverter/YamlToPhpConverterTest.php +++ b/tests/Converter/YamlToPhpConverter/YamlToPhpConverterTest.php @@ -5,24 +5,18 @@ namespace Symplify\ConfigTransformer\Tests\Converter\YamlToPhpConverter; use Symplify\ConfigTransformer\Converter\YamlToPhpConverter; -use Symplify\ConfigTransformer\Kernel\ConfigTransformerKernel; -use Symplify\PackageBuilder\Testing\AbstractKernelTestCase; +use Symplify\ConfigTransformer\Tests\AbstractTestCase; -final class YamlToPhpConverterTest extends AbstractKernelTestCase +final class YamlToPhpConverterTest extends AbstractTestCase { - private YamlToPhpConverter $yamlToPhpConverter; - - protected function setUp(): void - { - $this->bootKernel(ConfigTransformerKernel::class); - $this->yamlToPhpConverter = $this->getService(YamlToPhpConverter::class); - } - public function test(): void { - $printedPhpConfigContent = $this->yamlToPhpConverter->convertYamlArray([ + $yamlToPhpConverter = $this->getService(YamlToPhpConverter::class); + + $printedPhpConfigContent = $yamlToPhpConverter->convertYamlArray([ 'parameters' => [ 'key' => 'value', + 'format' => '\d+', ], ], 'file_path.yaml'); diff --git a/tests/Finder/ConfigFileFinder/ConfigFileFinderTest.php b/tests/Finder/ConfigFileFinder/ConfigFileFinderTest.php index b24ad033b01..18874bf2e62 100644 --- a/tests/Finder/ConfigFileFinder/ConfigFileFinderTest.php +++ b/tests/Finder/ConfigFileFinder/ConfigFileFinderTest.php @@ -4,27 +4,19 @@ namespace Symplify\ConfigTransformer\Tests\Finder\ConfigFileFinder; +use PHPUnit\Framework\TestCase; use Symplify\ConfigTransformer\Finder\ConfigFileFinder; -use Symplify\ConfigTransformer\Kernel\ConfigTransformerKernel; -use Symplify\ConfigTransformer\ValueObject\Configuration; -use Symplify\PackageBuilder\Testing\AbstractKernelTestCase; -final class ConfigFileFinderTest extends AbstractKernelTestCase +/** + * @see \Symplify\ConfigTransformer\Finder\ConfigFileFinder + */ +final class ConfigFileFinderTest extends TestCase { - private ConfigFileFinder $configFileFinder; - - protected function setUp(): void - { - $this->bootKernel(ConfigTransformerKernel::class); - - $this->configFileFinder = $this->getService(ConfigFileFinder::class); - } - public function test(): void { - $configuration = new Configuration([__DIR__ . '/Fixture'], true); + $configFileFinder = new ConfigFileFinder(); - $fileInfos = $this->configFileFinder->findFileInfos($configuration); + $fileInfos = $configFileFinder->findFileInfos([__DIR__ . '/Fixture']); $this->assertCount(1, $fileInfos); } } diff --git a/tests/Fixture/some.xml b/tests/Fixture/some.xml deleted file mode 100644 index f202ddcc505..00000000000 --- a/tests/Fixture/some.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - diff --git a/tests/Helper/FixtureFinder.php b/tests/Helper/FixtureFinder.php new file mode 100644 index 00000000000..172080a3f96 --- /dev/null +++ b/tests/Helper/FixtureFinder.php @@ -0,0 +1,26 @@ +> + */ + public static function yieldDirectory(string $directory, string $suffix = '*.php.inc'): Iterator + { + $finder = Finder::create()->in($directory)->files()->name($suffix); + + $fileInfos = iterator_to_array($finder->getIterator()); + + foreach ($fileInfos as $fileInfo) { + yield [$fileInfo]; + } + } +} diff --git a/tests/Helper/FixtureSplitter.php b/tests/Helper/FixtureSplitter.php new file mode 100644 index 00000000000..c94a1d611ef --- /dev/null +++ b/tests/Helper/FixtureSplitter.php @@ -0,0 +1,125 @@ +getContents(), self::SPLIT_LINE_REGEX)); + + // if more or less, it could be a test cases for monorepo line in it + if ($splitLineCount === 1) { + // input → expected + [$input, $expected] = Strings::split($smartFileInfo->getContents(), self::SPLIT_LINE_REGEX); + + $expected = self::retypeExpected($expected); + + return new InputAndExpected($input, $expected); + } + + // no changes + return new InputAndExpected($smartFileInfo->getContents(), $smartFileInfo->getContents()); + } + + public static function splitFileInfoToLocalInputAndExpectedFileInfos( + SplFileInfo $smartFileInfo, + bool $autoloadTestFixture = false, + bool $preserveDirStructure = false + ): InputFileInfoAndExpectedFileInfo { + $inputAndExpected = self::splitFileInfoToInputAndExpected($smartFileInfo); + + $prefix = ''; + if ($preserveDirStructure) { + $dir = explode('Fixture', $smartFileInfo->getRealPath(), 2); + $prefix = isset($dir[1]) ? dirname($dir[1]) . '/' : ''; + $prefix = ltrim($prefix, '/\\'); + } + + $inputFileInfo = self::createTemporaryFileInfo( + $smartFileInfo, + $prefix . 'input', + $inputAndExpected->getInput() + ); + + // some files needs to be autoload to enable reflection + if ($autoloadTestFixture) { + require_once $inputFileInfo->getRealPath(); + } + + $expectedFileInfo = self::createTemporaryFileInfo( + $smartFileInfo, + $prefix . 'expected', + $inputAndExpected->getExpected() + ); + + return new InputFileInfoAndExpectedFileInfo($inputFileInfo, $expectedFileInfo); + } + + public static function getTemporaryPath(): string + { + if (self::$customTemporaryPath !== null) { + return self::$customTemporaryPath; + } + + return sys_get_temp_dir() . '/_temp_fixture_easy_testing'; + } + + public static function createTemporaryFileInfo( + SplFileInfo $fixtureSmartFileInfo, + string $prefix, + string $fileContent + ): SplFileInfo { + $temporaryFilePath = self::createTemporaryPathWithPrefix($fixtureSmartFileInfo, $prefix); + $dir = dirname($temporaryFilePath); + if (! is_dir($dir)) { + mkdir($dir, 0777, true); + } + + FileSystem::write($temporaryFilePath, $fileContent); + return new SplFileInfo($temporaryFilePath, '', ''); + } + + private static function createTemporaryPathWithPrefix(SplFileInfo $smartFileInfo, string $prefix): string + { + $hash = Strings::substring(md5($smartFileInfo->getRealPath()), -20); + + $fileBasename = $smartFileInfo->getBasename('.inc'); + + return self::getTemporaryPath() . sprintf('/%s_%s_%s', $prefix, $hash, $fileBasename); + } + + private static function retypeExpected(mixed $expected): mixed + { + if (! is_numeric(trim((string) $expected))) { + return $expected; + } + + // value re-type + if (strlen((string) (int) $expected) === strlen(trim((string) $expected))) { + return (int) $expected; + } + + if (strlen((string) (float) $expected) === strlen(trim((string) $expected))) { + return (float) $expected; + } + + return $expected; + } +} diff --git a/tests/Helper/FixtureUpdater.php b/tests/Helper/FixtureUpdater.php new file mode 100644 index 00000000000..c47a2c7580d --- /dev/null +++ b/tests/Helper/FixtureUpdater.php @@ -0,0 +1,52 @@ +getRealPath(), $newOriginalContent); + } + + public static function updateExpectedFixtureContent( + string $newOriginalContent, + SplFileInfo $expectedFixtureFileInfo + ): void { + if (! getenv('UPDATE_TESTS') && ! getenv('UT')) { + return; + } + + FileSystem::write($expectedFixtureFileInfo->getRealPath(), $newOriginalContent); + } + + private static function resolveNewFixtureContent( + SplFileInfo|string $originalFileInfo, + string $changedContent + ): string { + if ($originalFileInfo instanceof SplFileInfo) { + $originalContent = $originalFileInfo->getContents(); + } else { + $originalContent = $originalFileInfo; + } + + if ($originalContent === $changedContent) { + return $originalContent; + } + + return $originalContent . '-----' . PHP_EOL . $changedContent; + } +} diff --git a/tests/Helper/ValueObject/InputAndExpected.php b/tests/Helper/ValueObject/InputAndExpected.php new file mode 100644 index 00000000000..c6a95b73061 --- /dev/null +++ b/tests/Helper/ValueObject/InputAndExpected.php @@ -0,0 +1,24 @@ +input; + } + + public function getExpected(): string + { + return $this->expected; + } +} diff --git a/tests/Helper/ValueObject/InputFileInfoAndExpectedFileInfo.php b/tests/Helper/ValueObject/InputFileInfoAndExpectedFileInfo.php new file mode 100644 index 00000000000..43d2e8ae007 --- /dev/null +++ b/tests/Helper/ValueObject/InputFileInfoAndExpectedFileInfo.php @@ -0,0 +1,36 @@ +inputFileInfo; + } + + public function getExpectedFileInfo(): SplFileInfo + { + return $this->expectedFileInfo; + } + + public function getExpectedFileContent(): string + { + return $this->expectedFileInfo->getContents(); + } + + public function getExpectedFileInfoRealPath(): string + { + return $this->expectedFileInfo->getRealPath(); + } +}