Skip to content

Commit

Permalink
Replace deprecated AnnotationsParser from Nette with BetterReflection
Browse files Browse the repository at this point in the history
  • Loading branch information
OndraM committed Nov 29, 2020
1 parent f4f7869 commit 3e76096
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 29 deletions.
1 change: 1 addition & 0 deletions composer.json
Expand Up @@ -36,6 +36,7 @@
"ondram/ci-detector": "^3.1",
"php-webdriver/webdriver": "^1.8.1",
"phpunit/phpunit": "^7.5",
"roave/better-reflection": "^4.3",
"symfony/console": "^4.0",
"symfony/event-dispatcher": "^4.0",
"symfony/filesystem": "^4.0",
Expand Down
1 change: 1 addition & 0 deletions easy-coding-standard.yaml
Expand Up @@ -18,3 +18,4 @@ parameters:
exclude_files:
- 'src-tests/coverage/*'
- 'src-tests/FunctionalTests/logs/coverage/*'
- 'src-tests/Utils/Annotations/Fixtures/*'
45 changes: 45 additions & 0 deletions src-tests/Utils/Annotations/ClassParserTest.php
@@ -0,0 +1,45 @@
<?php declare(strict_types=1);

namespace Lmc\Utils\Annotations;

use Lmc\Steward\Utils\Annotations\ClassParser;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Finder\SplFileInfo;

/**
* @covers \Lmc\Steward\Utils\Annotations\ClassParser
*/
class ClassParserTest extends TestCase
{
public function testShouldGetClassNameFromFile(): void
{
$file = $this->createFileInfo('ClassNoDocBlock.php');

$className = ClassParser::readClassNameFromFile($file);

$this->assertSame('Lmc\Steward\Utils\Fixtures\ClassNoDocBlock', $className);
}

public function testShouldThrowExceptionForMultipleClassesInOneFile(): void
{
$file = $this->createFileInfo('MultipleClassesInFile.php');

$this->expectException(\RuntimeException::class);
$this->expectExceptionMessageRegExp('/^File ".+MultipleClassesInFile.php" contains definition of 2 classes\./');
ClassParser::readClassNameFromFile($file);
}

public function testShouldThrowExceptionForNoClassInOneFile(): void
{
$file = $this->createFileInfo('NoClassInFile.php');

$this->expectException(\RuntimeException::class);
$this->expectExceptionMessageRegExp('/^No class found in file ".+NoClassInFile.php"/');
ClassParser::readClassNameFromFile($file);
}

private function createFileInfo(string $fileName): SplFileInfo
{
return new SplFileInfo(__DIR__ . '/Fixtures/' . $fileName, 'Fixtures/', 'Fixtures/' . $fileName);
}
}
7 changes: 7 additions & 0 deletions src-tests/Utils/Annotations/Fixtures/ClassNoDocBlock.php
@@ -0,0 +1,7 @@
<?php declare(strict_types=1);

namespace Lmc\Steward\Utils\Fixtures;

class ClassNoDocBlock
{
}
11 changes: 11 additions & 0 deletions src-tests/Utils/Annotations/Fixtures/MultipleClassesInFile.php
@@ -0,0 +1,11 @@
<?php declare(strict_types=1);

namespace Lmc\Steward\Utils\Fixtures;

class ClassFirst
{
}

class ClassSecond
{
}
9 changes: 9 additions & 0 deletions src-tests/Utils/Annotations/Fixtures/NoClassInFile.php
@@ -0,0 +1,9 @@
<?php declare(strict_types=1);

// In this file is no instantiable class declared

if (PHP_MAJOR_VERSION === 8) {
// do nothing
} else {
// do nothing as well
}
2 changes: 1 addition & 1 deletion src-tests/Utils/StringsTest.php
Expand Up @@ -12,7 +12,7 @@ class StringsTest extends TestCase
/**
* @dataProvider provideStringToFilename
*/
public function testShouldCOnvertStringToFilename(string $string, string $expectedFilename): void
public function testShouldConvertStringToFilename(string $string, string $expectedFilename): void
{
$this->assertSame($expectedFilename, Strings::toFilename($string));
}
Expand Down
6 changes: 2 additions & 4 deletions src/Console/EventListener/ListenerInstantiator.php
Expand Up @@ -2,11 +2,10 @@

namespace Lmc\Steward\Console\EventListener;

use Nette\Reflection\AnnotationsParser;
use Lmc\Steward\Utils\Annotations\ClassParser;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;

/**
* Search and instantiate event-listeners for the commands
Expand Down Expand Up @@ -48,9 +47,8 @@ protected function searchListeners(string $dir): array
->name('*Listener.php');

$listeners = [];
/** @var SplFileInfo $file */
foreach ($files as $file) {
$listeners[] = key(AnnotationsParser::parsePhp(\file_get_contents($file->getRealPath())));
$listeners[] = ClassParser::readClassNameFromFile($file);
}

return $listeners;
Expand Down
27 changes: 3 additions & 24 deletions src/Process/ProcessSetCreator.php
Expand Up @@ -7,6 +7,7 @@
use Lmc\Steward\Console\Configuration\ConfigOptions;
use Lmc\Steward\Console\Event\RunTestsProcessEvent;
use Lmc\Steward\Publisher\AbstractPublisher;
use Lmc\Steward\Utils\Annotations\ClassParser;
use Lmc\Steward\Utils\Strings;
use Nette\Reflection\AnnotationsParser;
use Symfony\Component\Console\Input\InputInterface;
Expand Down Expand Up @@ -84,7 +85,8 @@ public function createFromFiles(
/** @var SplFileInfo $file */
foreach ($files as $file) {
$fileName = $file->getRealPath();
$className = $this->getClassNameFromFile($fileName);
$className = ClassParser::readClassNameFromFile($file);

$annotations = $this->getClassAnnotations($className, $fileName);

if ($excludingGroups = $this->getExcludingGroups($excludeGroups, $annotations)) {
Expand Down Expand Up @@ -216,29 +218,6 @@ private function getExcludingGroups(array $excludeGroups, array $annotations): a
return $excludingGroups;
}

private function getClassNameFromFile(string $fileName): string
{
// Parse classes from the testcase file
$classes = AnnotationsParser::parsePhp(\file_get_contents($fileName));

if (empty($classes)) {
throw new \RuntimeException(sprintf('No class found in file "%s"', $fileName));
}

if (count($classes) > 1) {
throw new \RuntimeException(
sprintf(
'File "%s" contains definition of %d classes. However, each class must be defined in its own'
. ' separate file.',
$fileName,
count($classes)
)
);
}

return key($classes);
}

private function setupProcessDelays(ProcessWrapper $processWrapper, array $annotations): void
{
$delayAfter = !empty($annotations['delayAfter']) ? current($annotations['delayAfter']) : '';
Expand Down
41 changes: 41 additions & 0 deletions src/Utils/Annotations/ClassParser.php
@@ -0,0 +1,41 @@
<?php declare(strict_types=1);

namespace Lmc\Steward\Utils\Annotations;

use Roave\BetterReflection\BetterReflection;
use Roave\BetterReflection\Reflector\ClassReflector;
use Roave\BetterReflection\SourceLocator\Type\SingleFileSourceLocator;
use Symfony\Component\Finder\SplFileInfo;

class ClassParser
{
public static function readClassNameFromFile(SplFileInfo $file): string
{
$reflection = new ClassReflector(
new SingleFileSourceLocator($file->getRealPath(), (new BetterReflection())->astLocator())
);

$classesInFile = $reflection->getAllClasses();
self::assertOneClassInFile($classesInFile, $file);

return $classesInFile[0]->getName();
}

private static function assertOneClassInFile(array $classesInFile, SplFileInfo $file): void
{
if (count($classesInFile) === 0) {
throw new \RuntimeException(sprintf('No class found in file "%s"', $file->getRelativePathname()));
}

if (count($classesInFile) > 1) {
throw new \RuntimeException(
sprintf(
'File "%s" contains definition of %d classes. However, each class must be defined in its own'
. ' separate file.',
$file->getRelativePathname(),
count($classesInFile)
)
);
}
}
}

0 comments on commit 3e76096

Please sign in to comment.