Last active
March 11, 2021 15:33
-
-
Save mfn/e865d539010d1ed78bc1b16cfe15b2cc to your computer and use it in GitHub Desktop.
Take the output of https://gist.github.com/mfn/256636242cbe8a51252ce28181a6b074 and rewrite an existing phpunit.xml to use only these test classes (mapped to files)
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 characters
#!/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)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment