Skip to content

Commit

Permalink
refactor(testcmd): remove dumpautoload, reuse metadata logic from bas…
Browse files Browse the repository at this point in the history
…e command
  • Loading branch information
adhocore committed Aug 25, 2018
1 parent dc07912 commit 964ffbe
Showing 1 changed file with 28 additions and 89 deletions.
117 changes: 28 additions & 89 deletions src/Console/TestCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ protected function onConstruct()
->option('-n --naming', "Test method naming format\n(t: testMethod | m: test_method | i: it_tests_)")
->option('-a --with-abstract', 'Create stub for abstract/interface class')
->option('-p --phpunit [classFqcn]', 'Base PHPUnit class to extend from')
->option('-d --dump-autoload', 'Force composer dumpautoload (slow)', null, false)
->option('-x --template', "User supplied template path\nIt has higher precedence than inbuilt templates")
->usage(
'<bold> phint test</end> <comment>-n i</end> With `it_` naming<eol/>' .
Expand All @@ -53,9 +52,7 @@ public function interact(Interactor $io)
'default' => 't',
],
'phpunit' => [
'default' => \class_exists('\\PHPUnit\\Framework\\TestCase')
? 'PHPUnit\\Framework\\TestCase'
: 'PHPUnit_Framework_TestCase',
'default' => 'PHPUnit\\Framework\\TestCase',
],
'template' => false,
];
Expand All @@ -73,12 +70,6 @@ public function execute()
{
$io = $this->app()->io();

// Generate namespace mappings
if ($this->dumpAutoload) {
$io->colors('Running <cyanBold>composer dumpautoload</end> <comment>(takes some time)</end><eol>');
$this->_composer->dumpAutoload();
}

$io->comment('Preparing metadata ...', true);
$metadata = $this->prepare();

Expand All @@ -105,105 +96,53 @@ protected function prepare(): array
$namespaces = $this->_composer->config('autoload.psr-4');
$namespaces += $this->_composer->config('autoload-dev.psr-4');

$testNs = [];
foreach ($namespaces as $ns => $path) {
if (!\preg_match('!src/?|lib/?!', $path)) {
unset($namespaces[$ns]);
}
$srcNs = $testNs = [];

if (\strpos($path, 'test') === 0) {
$path = \rtrim($path, '/\\');
$nsPath = "{$this->_workDir}/$path";
$testNs = \compact('ns', 'nsPath');
} elseif ([] === $testNs) {
$ns = $ns . '\\Test';
$nsPath = "{$this->_workDir}/tests";
$testNs = \compact('ns', 'nsPath');
foreach ($namespaces as $ns => $path) {
$ns = \rtrim($ns, '\\') . '\\';
if (\preg_match('!^(source|src|lib|class)/?!', $path)) {
$path = \rtrim($path, '/\\') . '/';
$srcNs[] = ['ns' => $ns, 'nsPath' => "{$this->_workDir}/$path"];
} elseif (\strpos($path, 'test') === 0) {
$path = \rtrim($path, '/\\') . '/';
$testNs = ['ns' => $ns, 'nsPath' => "{$this->_workDir}/$path"];
}
}

$classMap = require $this->_workDir . '/vendor/composer/autoload_classmap.php';

return $this->getTestMetadata($classMap, $namespaces, $testNs);
}

protected function getTestMetadata(array $classMap, array $namespaces, array $testNs): array
{
$testMeta = [];

require_once $this->_workDir . '/vendor/autoload.php';

foreach ($classMap as $classFqcn => $classPath) {
foreach ($namespaces as $ns => $nsPath) {
if (\strpos($classFqcn, $ns) !== 0 || \strpos($classFqcn, $testNs['ns']) === 0) {
continue;
}

if ([] === $meta = $this->getClassMetadata($classFqcn, $testNs['ns'])) {
continue;
}

$data = \compact('classFqcn', 'classPath', 'ns', 'nsPath');
$testMeta[] = $meta + $this->convertToTest($data, $testNs);
}
if (empty($srcNs) || empty($testNs)) {
throw new \RuntimeException(
'The composer.json#(autoload.psr-4, autoload-dev.psr-4) contains no `src` or `test` paths'
);
}

return $testMeta;
return $this->getTestMetadata($this->getSourceClasses(), $srcNs, $testNs);
}

protected function getClassMetadata(string $classFqcn): array
protected function getTestMetadata(array $classes, array $srcNs, array $testNs): array
{
$reflex = new \ReflectionClass($classFqcn);

if (!$this->shouldGenerateTest($reflex)) {
return [];
}

$methods = [];
$isTrait = $reflex->isTrait();
$newable = $reflex->isInstantiable();
$isAbstract = $reflex->isAbstract();
$isInterface = $reflex->isInterface();
$excludes = ['__construct', '__destruct'];
$metadata = [];

foreach ($reflex->getMethods(\ReflectionMethod::IS_PUBLIC) as $m) {
if ($m->class !== $classFqcn || \in_array($m->name, $excludes)) {
foreach ($classes as $classFqcn) {
if ([] === $meta = $this->getClassMetaData($classFqcn)) {
continue;
}

$methods[\ltrim($m->name, '_')] = ['static' => $m->isStatic(), 'abstract' => $m->isAbstract()];
$metadata[] = $meta + $this->convertToTest($meta, $srcNs, $testNs);
}

return \compact('classFqcn', 'isTrait', 'isAbstract', 'isInterface', 'newable', 'methods');
return $metadata;
}

protected function shouldGenerateTest(\ReflectionClass $reflex): bool
private function convertToTest(array $metadata, array $srcNs, array $testNs): array
{
if ($reflex->isSubclassOf(\Throwable::class)) {
return false;
}
$testClass = $metadata['className'] . 'Test';
$testPath = \str_replace(\array_column($srcNs, 'nsPath'), $testNs['nsPath'], $metadata['classPath']);
$testPath = \preg_replace('!\.php$!i', 'Test.php', $testPath);
$testFqcn = \str_replace(\array_column($srcNs, 'ns'), $testNs['ns'], $metadata['classFqcn']) . 'Test';

if ($this->abstract) {
return true;
}
$testNamespace = \str_replace(\array_column($srcNs, 'ns'), $testNs['ns'], $metadata['namespace']);

return !$reflex->isInterface() && !$reflex->isAbstract();
}

private function convertToTest(array $metadata, array $testNs): array
{
$classFqcn = $metadata['classFqcn'];
$classPath = \realpath($metadata['classPath']);
$nsFullPath = $this->_workDir . '/' . \trim($metadata['nsPath'], '/\\') . '/';
$testPath = \preg_replace('!^' . \preg_quote($nsFullPath) . '!', $testNs['nsPath'] . '/', $classPath);
$testPath = \preg_replace('!\.php$!i', 'Test.php', $testPath);
$testFqcn = \preg_replace('!^' . \preg_quote($metadata['ns']) . '!', $testNs['ns'], $classFqcn);
$fqcnParts = \explode('\\', $testFqcn);
$className = \array_pop($fqcnParts);
$testFqns = \implode('\\', $fqcnParts);
$testFqcn = $testFqcn . '\\Test';

return compact('className', 'testFqns', 'testFqcn', 'testPath');
return compact('testClass', 'testNamespace', 'testFqcn', 'testPath');
}

protected function generate(array $testMetadata, array $parameters): int
Expand Down

0 comments on commit 964ffbe

Please sign in to comment.