Last active
March 4, 2017 15:04
-
-
Save Hywan/b8bd387def5e3cc13e024c4f924e8c3c to your computer and use it in GitHub Desktop.
Address RFC 52 from Hoa
This file contains 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
<?php | |
require 'vendor/autoload.php'; | |
use Hoa\File; | |
use League\CommonMark; | |
const DIRECTORY_TO_SCAN = '../Acl'; | |
const NAMESPACE_TO_SCAN = 'Hoa\\\Acl\\\\'; | |
const DOCUMENTATION_SECTION = 'Examples'; | |
require DIRECTORY_TO_SCAN . '/vendor/autoload.php'; | |
$finder = new File\Finder(); | |
$finder | |
->files() | |
->name('/\.php$/') | |
->in(DIRECTORY_TO_SCAN) | |
->notIn('/^\.git|vendor|Test$/'); | |
$classes = get_declared_classes(); | |
foreach ($finder as $file) { | |
require_once $file->getPathName(); | |
} | |
$reflectedClasses = []; | |
foreach (array_diff(get_declared_classes(), $classes) as $class) { | |
if (0 === preg_match('/^' . NAMESPACE_TO_SCAN . '/', $class)) { | |
continue; | |
} | |
$reflectedClasses[] = new ReflectionClass($class); | |
} | |
unset($classes); | |
$markdown = new CommonMark\DocParser(CommonMark\Environment::createCommonMarkEnvironment()); | |
$testSuites = []; | |
foreach ($reflectedClasses as $reflectedClass) { | |
$testSuite = sprintf( | |
'<?php' . "\n\n" . | |
'namespace Hoa\Foo\Test\Documentation;' . "\n\n" . | |
'use Hoa\Test;' . "\n\n" . | |
'class %s extends Test\Integration\Suite' . "\n" . | |
'{', | |
$reflectedClass->getShortName() | |
); | |
$anyTestCase = false; | |
foreach ($reflectedClass->getMethods() as $reflectedMethod) { | |
$comment = $reflectedMethod->getDocComment(); | |
if (false === $comment) { | |
continue; | |
} | |
$comment = extractFromComment($comment); | |
$examples = collectExamples($markdown->parse($comment)->walker()); | |
if (empty($examples)) { | |
continue; | |
} | |
$anyTestCase = true; | |
$testCaseIndex = 0; | |
foreach ($examples as $example) { | |
$testSuite .= sprintf( | |
"\n" . | |
' public function case_%s_example_%d()' . "\n" . | |
' {' . "\n" . | |
'%s' . "\n" . | |
' }' . "\n", | |
$reflectedMethod->getName(), | |
$testCaseIndex, | |
compileExampleToTestCaseBody($example) | |
); | |
$testCaseIndex++; | |
} | |
} | |
$testSuite .= '}'; | |
if (true === $anyTestCase) { | |
$testSuites[$reflectedClass->getName()] = $testSuite; | |
} | |
} | |
var_dump($testSuites); | |
function extractFromComment(string $comment): string | |
{ | |
return preg_replace( | |
',^(/\*\*|\h*\*/?\h*),m', | |
'', | |
$comment | |
); | |
} | |
function collectExamples(CommonMark\Node\NodeWalker $walker): array | |
{ | |
while ($event = $walker->next()) { | |
$node = $event->getNode(); | |
if (false === $event->isEntering() || | |
!($node instanceof CommonMark\Block\Element\Heading) || | |
1 !== $node->getLevel() || | |
DOCUMENTATION_SECTION !== $node->getStringContent()) { | |
continue; | |
} | |
$examples = []; | |
while ($childEvent = $walker->next()) { | |
$childNode = $childEvent->getNode(); | |
if ($childNode instanceof CommonMark\Block\Element\Heading && | |
DOCUMENTATION_SECTION !== $childNode->getStringContent()) { | |
break; | |
} | |
if (false === $event->isEntering() || | |
!($childNode instanceof CommonMark\Block\Element\FencedCode)) { | |
continue; | |
} | |
$hash = spl_object_hash($childNode); | |
if (isset($examples[$hash])) { | |
continue; | |
} | |
$codeBlock = new CodeBlock(); | |
$codeBlock->type = $childNode->getInfo(); | |
$codeBlock->code = trim($childNode->getStringContent()); | |
$examples[$hash] = $codeBlock; | |
} | |
return $examples; | |
} | |
return []; | |
} | |
function compileExampleToTestCaseBody(CodeBlock $example): string | |
{ | |
return sprintf( | |
' $this' . "\n" . | |
' ->do(function () {' . "\n" . | |
' %s' . "\n" . | |
' });' . "\n", | |
preg_replace( | |
'/^\h+$/m', | |
'', | |
str_replace("\n", "\n" . ' ', $example->code) | |
) | |
); | |
} | |
class CodeBlock | |
{ | |
public $type = null; | |
public $code = null; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment