Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/code_analysis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ jobs:
name: 'Finalize classes'
run: vendor/bin/swiss-knife finalize-classes src tests --dry-run

-
name: 'Check before/after test fixture on no-changes'
run: php bin/check-before-after-same-fixtures.php
Copy link
Member Author

@TomasVotruba TomasVotruba Aug 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@samsonasik This might help with code reviews 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TomasVotruba the files seems commited on scoped vendor, should it be removed before scoped?

rectorphp/rector@d2d451e#diff-6a943cc1e536167118f5fb8160e164027ae139c4986d1e324a1faabbd1f39b36

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Indeed, should be removed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


-
name: 'Check no "*.php" files in rules Fixture directory'
run: php bin/no-php-file-in-fixtures.php

-
name: 'Detect composer dependency issues'
run: vendor/bin/composer-dependency-analyser
Expand Down
85 changes: 85 additions & 0 deletions bin/check-before-after-same-fixtures.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

declare(strict_types=1);

use Nette\Utils\Strings;

require __DIR__ . '/../vendor/autoload.php';

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;
use Webmozart\Assert\Assert;

final readonly class SameBeforeAfterFixtureDetector
{
private SymfonyStyle $symfonyStyle;

public function __construct()
{
$this->symfonyStyle = new SymfonyStyle(new ArgvInput(), new ConsoleOutput());
}

/**
* @param string[] $testDirectories
* @return Command::SUCCESS|Command::FAILURE
*/
public function run(array $testDirectories): int
{
$fixtureFiles = $this->findFixtureFiles($testDirectories);

$invalidFixturePaths = [];
foreach ($fixtureFiles as $fixtureFile) {
if (! $this->hasFileSameBeforeAndAfterPart($fixtureFile)) {
continue;
}

$invalidFixturePaths[] = substr($fixtureFile->getRealPath(), strlen(getcwd()) + 1);
}

if ($invalidFixturePaths === []) {
$this->symfonyStyle->success('All fixtures are valid');
return Command::SUCCESS;
}

$this->symfonyStyle->error(
'The following fixtures have the same before and after content. Remove the part after "-----" to fix them'
);
$this->symfonyStyle->listing($invalidFixturePaths);

return Command::FAILURE;
}

/**
* @param string[] $directories
* @return SplFileInfo[]
*/
private function findFixtureFiles(array $directories): array
{
Assert::allDirectory($directories);

$finder = (new Finder())
->files()
->in($directories)
->name('*.php.inc')
->sortByName();

return iterator_to_array($finder->getIterator());
}

private function hasFileSameBeforeAndAfterPart(SplFileInfo $fixtureFile): bool
{
$parts = Strings::split($fixtureFile->getContents(), '#^\s*-----\s*$#m');
if (count($parts) !== 2) {
return false;
}

return trim((string) $parts[0]) === trim((string) $parts[1]);
}
}

$sameBeforeAfterFixtureDetector = new SameBeforeAfterFixtureDetector();
exit($sameBeforeAfterFixtureDetector->run([__DIR__ . '/../tests', __DIR__ . '/../rules-tests']));
109 changes: 109 additions & 0 deletions bin/no-php-file-in-fixtures.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php

declare(strict_types=1);

require __DIR__ . '/../vendor/autoload.php';

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;
use Webmozart\Assert\Assert;

final readonly class NoPhpFileInFixturesDetector
{
/**
* @var string[]
*/
private const EXCLUDED_FILES = [
// on-purpose as same namespace text
'rules-tests/Renaming/Rector/Name/RenameClassRector/FixtureAutoImportNames/SomeShort.php',
];

private SymfonyStyle $symfonyStyle;

public function __construct()
{
$this->symfonyStyle = new SymfonyStyle(new ArgvInput(), new ConsoleOutput());
}

/**
* @param string[] $testDirectories
* @return Command::SUCCESS|Command::FAILURE
*/
public function run(array $testDirectories): int
{
$phpFiles = $this->findPhpFiles($testDirectories);

$allFixtureFiles = $this->findFixtureFiles($testDirectories);

$relativePhpFiles = [];
foreach ($phpFiles as $phpFile) {
$relativeFilePath = substr($phpFile->getRealPath(), strlen(getcwd()) + 1);

// should skip?
if (in_array($relativeFilePath, self::EXCLUDED_FILES, true)) {
continue;
}

$relativePhpFiles[] = $relativeFilePath;
}

if ($relativePhpFiles === []) {
$this->symfonyStyle->success(sprintf('All %d fixtures are valid', count($allFixtureFiles)));
return Command::SUCCESS;
}

$this->symfonyStyle->error(
'The following "*.php* files were found in /Fixtures directory, but only "*.php.inc" files are picked up and allowed. Rename their suffix or remove them'
);
$this->symfonyStyle->listing($relativePhpFiles);

return Command::FAILURE;
}

/**
* @param string[] $directories
* @return SplFileInfo[]
*/
private function findPhpFiles(array $directories): array
{
Assert::allDirectory($directories);

$finder = (new Finder())
->files()
->in($directories)
->path('/Fixture')
->path('/Fixture*')
->notPath('Source')
->name('*.php')
->sortByName();

return iterator_to_array($finder->getIterator());
}

/**
* @param string[] $directories
* @return SplFileInfo[]
*/
private function findFixtureFiles(array $directories): array
{
Assert::allDirectory($directories);

$finder = (new Finder())
->files()
->in($directories)
->path('Fixture')
->path('Fixture*')
->notPath('Source')
->sortByName();

return iterator_to_array($finder->getIterator());
}
}

$noPhpFileInFixturesDetector = new NoPhpFileInFixturesDetector();

exit($noPhpFileInFixturesDetector->run([__DIR__ . '/../rules-tests']));
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,3 @@ class StaticProperty
return $this::$privateProperty;
}
}

?>
-----
<?php

namespace Rector\Tests\DeadCode\Rector\Property\RemoveUnusedPrivatePropertyRector\Fixture;

class StaticProperty
{
public static $publicProperty;
protected static $protectedProperty;

public function foo()
{
return $this::$privateProperty;
}
}

?>
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,3 @@ abstract class FinalPrivate
{
}
}

?>
-----
<?php

namespace Rector\Tests\Php80\Rector\ClassMethod\FinalPrivateToPrivateVisibilityRector\Fixture;

abstract class FinalPrivate
{
final private function __construct()
{
}
}

?>
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,3 @@ function bar($otherObject): void
$finfo->buffer($fileContents, FILEINFO_NONE, context: $context);
$finfo->buffer($fileContents, flags: FILEINFO_NONE, context: $context);
}

?>
-----
<?php

declare(strict_types=1);

namespace Rector\Tests\Php85\Rector\FuncCall\RemoveFinfoBufferContextArgRector\Fixture;

finfo_file($finfo, $fileContents, FILEINFO_NONE, $context);
finfo_file($finfo, $fileContents, FILEINFO_NONE, context: $context);
finfo_file($finfo, $fileContents, flags: FILEINFO_NONE, context: $context);

function foo(\finfo $finfo): void
{
$finfo->file($fileContents, FILEINFO_NONE, $context);
$finfo->file($fileContents, FILEINFO_NONE, context: $context);
$finfo->file($fileContents, flags: FILEINFO_NONE, context: $context);
}

function bar($otherObject): void
{
$finfo->buffer($fileContents, FILEINFO_NONE, $context);
$finfo->buffer($fileContents, FILEINFO_NONE, context: $context);
$finfo->buffer($fileContents, flags: FILEINFO_NONE, context: $context);
}

?>
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\Renaming\Rector\Cast\RenameCastRector;

use Iterator;
use PHPUnit\Framework\Attributes\DataProvider;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;

class RenameCastRectorTest extends AbstractRectorTestCase
final class RenameCastRectorTest extends AbstractRectorTestCase
{
#[DataProvider('provideData')]
public function test(string $filePath): void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,3 @@ final class ArrayReverseIndex
return sprintf('%d-%s', $index, $uri);
}
}

?>
-----
<?php

namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\AddMethodCallBasedStrictParamTypeRector\FixtureUnion;

final class ArrayReverseIndex
{
public function run()
{
$parts = array_reverse(explode('/', '/some/test/url'));
foreach ($parts as $index => $uri) {
if ($index === 0) {
continue;
}

$this->someOtherMethod($index, $uri);
}
}

private function someOtherMethod(int $index, string $uri)
{
return sprintf('%d-%s', $index, $uri);
}
}

?>
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,3 @@ final class ReturnInsideInnerFunction
};
}
}

?>
-----
<?php

namespace Rector\Tests\TypeDeclaration\Rector\Closure\AddClosureVoidReturnTypeWhereNoReturnRector\Fixture;

final class ReturnInsideInnerFunction
{
public function getValues()
{
$result = function () {
$value = 1000;
if ($value) {
return;
}

return 10;
};
}
}

?>
Loading
Loading