Last active
March 11, 2021 15:33
-
-
Save mfn/e865d539010d1ed78bc1b16cfe15b2cc to your computer and use it in GitHub Desktop.
Revisions
-
mfn renamed this gist
Mar 11, 2021 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
mfn created this gist
Mar 11, 2021 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,88 @@ #!/usr/bin/env php <?php declare(strict_types = 1); $command = array_shift($argv); if (3 !== count($argv)) { echo <<<USAGE Usage: $command path/to/composer.json path/to/phpunit.xml path/to/slice.xml > new_phpunit.xml Based on your composer PSR-4 autoload configuration, the classes referenced in slice.xml will be converted to test files and replace any <testsuites> in your phpunit.xml with a list of all the files. USAGE; exit(1); } $composerJson = json_decode(file_get_contents($argv[0]), true, 512, JSON_THROW_ON_ERROR); $psr4Autoloaders = array_merge( $composerJson['autoload-dev']['psr-4'] ?? [], $composerJson['autoload']['psr-4'] ?? [], ); if (!$psr4Autoloaders) { throw new RuntimeException('No PSR-4 autoloaders found in composer.json!'); } $mapper = new MapClassToFile($psr4Autoloaders); $classes = []; $slicedXml = simplexml_load_file($argv[2]); foreach ($slicedXml->testCaseClass as $class) { $classes[$class['name']->__toString()] = true; } unset($slicedXml); $phpunitXml = simplexml_load_file($argv[1]); // Remove all existing suites unset($phpunitXml->testsuites->testsuite); $testsuite = $phpunitXml->testsuites->addChild('testsuite'); $testsuite->addAttribute('name', $argv[2]); foreach (array_keys($classes) as $class) { $file = $mapper->map($class); $testsuite->addChild('file', $file); } echo $phpunitXml->asXML(); class MapClassToFile { private array $psr4Autoloaders; public function __construct(array $psr4Autoloaders) { $this->psr4Autoloaders = $psr4Autoloaders; } public function map(string $class): string { foreach ($this->psr4Autoloaders as $namespacePrefix => $directory) { if ($this->startsWith($class, $namespacePrefix)) { $file = substr($class, strlen($namespacePrefix)); $file = str_replace('\\', DIRECTORY_SEPARATOR, $file); return "$directory$file.php"; } } $msg = "Did not find a matching namespace for class $class in PSR-4 autoloaders found in composer.json: "; $msg .= json_encode($this->psr4Autoloaders); throw new RuntimeException($msg); } /** * Starts the $haystack string with the prefix $needle? */ private function startsWith(string $haystack, string $needle): bool { return 0 === strncmp($haystack, $needle, strlen($needle)); } }