Skip to content

Instantly share code, notes, and snippets.

@thanosp
Last active April 7, 2017 07:36
Show Gist options
  • Save thanosp/510b2cd9a52ed544d1255c22f746e884 to your computer and use it in GitHub Desktop.
Save thanosp/510b2cd9a52ed544d1255c22f746e884 to your computer and use it in GitHub Desktop.
<?php
declare(strict_types=1);
namespace Tests\Endouble\Sanity;
use Generator;
use SplFileInfo;
use SplFileObject;
use Symfony\Component\Finder\Finder;
use Tests\Endouble\UnitTestCase;
class PHPStrictnessTest extends UnitTestCase
{
/**
* @var array
*/
private $getterExceptions = [
'CommandBusEvent::getCommand',
'FunctionalTestCase::getReference',
];
/**
* @dataProvider getPHPFilesForStrictness
*
* @param SplFileInfo $file
*/
public function testFileUsesStrictTypes(SplFileInfo $file)
{
$fileObject = new SplFileObject($file->getPathname());
$fileObject->seek(1);
$firstFileLineContents = $fileObject->current();
if ($firstFileLineContents === false) {
$this->fail('Empty file found');
}
$this->assertEquals(
'declare(strict_types=1);',
trim($firstFileLineContents, PHP_EOL),
sprintf('%s does not enforce strict_types (with PSR-12 standards)', realpath($file->getPathname()))
);
}
/**
* @dataProvider getPHPFilesForStrictness
*
* @param SplFileInfo $file
*/
public function testFileGettersHaveReturnTypes(SplFileInfo $file)
{
$fileObject = new SplFileObject($file->getPathname());
foreach ($fileObject as $lineNumber => $line) {
if (preg_match('/function (((is|has)[A-Z]+|get|find)[A-Za-z]+)\(.*\)/', $line, $matches) !== 1) {
continue;
}
$getterName = $matches[1];
$fileIdentifier = $file->getBasename('.php') . '::' . $getterName;
if (in_array($fileIdentifier, $this->getterExceptions, true)) {
continue;
}
$lineHasReturnType = (preg_match('/: [A-Za-z]+;?$/', $line) === 1);
$errorMessage = sprintf(
'%s does not have a return type (with PSR-12 standards) in file %s:%d',
$getterName,
realpath($file->getPathname()),
$lineNumber
);
$this->assertTrue($lineHasReturnType, $errorMessage);
}
}
/**
* @dataProvider getPHPFilesForStrictness
*
* @param SplFileInfo $file
*/
public function testFileSettersHaveStrictArguments(SplFileInfo $file)
{
$fileObject = new SplFileObject($file->getPathname());
foreach ($fileObject as $lineNumber => $line) {
if (preg_match('/function (set[A-Za-z]+)\((.+)\)/', $line, $matches) !== 1) {
continue;
}
$getterName = $matches[1];
$arguments = $matches[2];
$fileIdentifier = $file->getBasename('.php') . '::' . $getterName;
if (in_array($fileIdentifier, $this->getterExceptions, true)) {
continue;
}
$lineHasStrictArgument = (preg_match('/(^\$)|(\, *\$)/', $arguments) === 0);
$errorMessage = sprintf(
'%s should use type hinting in file %s:%d',
$getterName,
realpath($file->getPathname()),
$lineNumber
);
$this->assertTrue($lineHasStrictArgument, $errorMessage);
}
}
/**
* Finds php files to force strict_types on them
*
* @return Generator
*/
public static function getPHPFilesForStrictness(): Generator
{
$finder = new Finder();
$finder->in([
__DIR__ . '/../../src',
__DIR__ . '/../../tests',
]);
$finder->filter(function (SplFileInfo $filename) {
return preg_match('/\.php$/', $filename->getPathname()) === 1;
});
/** @var SplFileInfo $file */
foreach ($finder->files()->getIterator() as $file) {
yield [$file];
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment