From 1b309bd7097a807f58a19015083c7fbad601ea52 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Thu, 6 Apr 2017 10:39:24 +0200 Subject: [PATCH] WIP|FEATURE: First working test * Parses fixtures to auto run tests for sniffs. * Compares actual result for fixture input against expected result from fixture. Relates: #46 --- composer.json | 7 +- .../ExpectedOutputForIssues.json | 33 ++++ .../DocCommentSniff/InputFileForIssues.php | 32 ++++ tests/SniffsTest.php | 157 ++++++++++++++++++ 4 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 tests/Fixtures/Standards/Typo3Update/Sniffs/LegacyClassnames/DocCommentSniff/ExpectedOutputForIssues.json create mode 100644 tests/Fixtures/Standards/Typo3Update/Sniffs/LegacyClassnames/DocCommentSniff/InputFileForIssues.php create mode 100644 tests/SniffsTest.php diff --git a/composer.json b/composer.json index e7cd2b5..0db31eb 100644 --- a/composer.json +++ b/composer.json @@ -4,6 +4,7 @@ "type": "project", "autoload": { "psr-4": { + "Typo3Update\\Tests\\": "tests/", "Typo3Update\\": "src/Standards/Typo3Update/" }, "files": [ @@ -27,5 +28,9 @@ "name": "Daniel Siepmann", "email": "coding@daniel-siepmann.de" } - ] + ], + "require-dev": { + "phpunit/phpunit": "^5.7", + "symfony/finder": "^3.2" + } } diff --git a/tests/Fixtures/Standards/Typo3Update/Sniffs/LegacyClassnames/DocCommentSniff/ExpectedOutputForIssues.json b/tests/Fixtures/Standards/Typo3Update/Sniffs/LegacyClassnames/DocCommentSniff/ExpectedOutputForIssues.json new file mode 100644 index 0000000..b70120f --- /dev/null +++ b/tests/Fixtures/Standards/Typo3Update/Sniffs/LegacyClassnames/DocCommentSniff/ExpectedOutputForIssues.json @@ -0,0 +1,33 @@ +{ + "files": { + "InputFileForIssues.php": { + "errors": 2, + "messages": [ + { + "column": 15, + "fixable": true, + "line": 25, + "message": "Legacy classes are not allowed; found \"t3lib_div\", use \"TYPO3\\CMS\\Core\\Utility\\GeneralUtility\" instead", + "severity": 5, + "source": "Typo3Update.LegacyClassnames.DocComment.legacyClassname", + "type": "ERROR" + }, + { + "column": 16, + "fixable": true, + "line": 27, + "message": "Legacy classes are not allowed; found \"Tx_Extbase_Configuration_Configurationmanager\", use \"TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManager\" instead", + "severity": 5, + "source": "Typo3Update.LegacyClassnames.DocComment.legacyClassname", + "type": "ERROR" + } + ], + "warnings": 0 + } + }, + "totals": { + "errors": 2, + "fixable": 2, + "warnings": 0 + } +} diff --git a/tests/Fixtures/Standards/Typo3Update/Sniffs/LegacyClassnames/DocCommentSniff/InputFileForIssues.php b/tests/Fixtures/Standards/Typo3Update/Sniffs/LegacyClassnames/DocCommentSniff/InputFileForIssues.php new file mode 100644 index 0000000..bcee6c5 --- /dev/null +++ b/tests/Fixtures/Standards/Typo3Update/Sniffs/LegacyClassnames/DocCommentSniff/InputFileForIssues.php @@ -0,0 +1,32 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +class InputFileForIssues +{ + /** + * @param t3lib_div + * + * @return Tx_Extbase_Configuration_Configurationmanager + */ + public function doSomething($something) + { + } +} diff --git a/tests/SniffsTest.php b/tests/SniffsTest.php new file mode 100644 index 0000000..49ebd4a --- /dev/null +++ b/tests/SniffsTest.php @@ -0,0 +1,157 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Finder\Finder; +use Symfony\Component\Finder\SplFileInfo; + +/** + * Will test all sniffs where fixtures are available. + * + * To add a test, just create the necessary fixture folder structure with files. + */ +class SniffsTest extends TestCase +{ + /** + * Get all fixtures for sniffs. + * + * Execute each sniff based on found fixtures and compare result. + * + * @test + */ + public function sniffs() + { + $finder = new Finder(); + $finder->in( + __DIR__ + . DIRECTORY_SEPARATOR . 'Fixtures' + . DIRECTORY_SEPARATOR . 'Standards' + . DIRECTORY_SEPARATOR . 'Typo3Update' + . DIRECTORY_SEPARATOR . 'Sniffs' + ); + + foreach ($finder->directories()->name('*Sniff') as $folder) { + $this->executeSniff($folder); + } + } + + /** + * Execute phpunit assertion for sniff based on $folder. + * + * @param SplFileInfo $folder + * @return void + */ + protected function executeSniff(SplFileInfo $folder) + { + $this->assertEquals( + $this->getExpectedOutput($folder), + $this->getOutput($folder)['output'], + 'Sniff ' . $this->getSniffByFolder($folder) + . ' did not produce expected output for input file ' + . $this->getExpectedOutputFile($folder) + ); + } + + /** + * Returns PHPCS Sniff name for given folder. + * + * @param SplFileInfo $folder + * @return string + */ + protected function getSniffByFolder(SplFileInfo $folder) + { + $folderParts = explode(DIRECTORY_SEPARATOR, $folder->getPath()); + return array_slice($folderParts, -3)[0] + . '.' . array_slice($folderParts, -1)[0] + . '.' . substr($folder->getFilename(), 0, -5); + } + + /** + * Returns absolute file path to json file containing expected output. + * + * @param SplFileInfo $folder + * @return string + */ + protected function getExpectedOutputFile(SplFileInfo $folder) + { + return $folder->getRealPath() . DIRECTORY_SEPARATOR . 'ExpectedOutputForIssues.json'; + } + + /** + * Get expected output for comparison. + * + * @param SplFileInfo $folder + * @return array + */ + protected function getExpectedOutput(SplFileInfo $folder) + { + return json_decode( + file_get_contents($this->getExpectedOutputFile($folder)), + true + ); + } + + /** + * Executes phpcs for sniff based on $folder and returns the generated output. + * + * @param SplFileInfo $folder + * @return array + */ + protected function getOutput(SplFileInfo $folder) + { + $bin = './vendor/bin/phpcs'; + $arguments = '--sniffs=' . $this->getSniffByFolder($folder) + . ' --report=json' + . ' ' + . $folder->getRealPath() . DIRECTORY_SEPARATOR . 'InputFileForIssues.php' + ; + $output = ''; + $returnValue; + + exec($bin . ' ' . $arguments, $output, $returnValue); + + return [ + 'output' => $this->prepareOutput($output), + 'returnValue' => $returnValue, + ]; + } + + /** + * Prepare phpcs output for comparison. + * + * @param array $output + * @return array + */ + protected function prepareOutput(array $output) + { + $preparedOutput = json_decode($output[0], true); + + foreach (array_keys($preparedOutput['files']) as $fileName) { + $newKey = basename($fileName); + $preparedOutput['files'][$newKey] = $preparedOutput['files'][$fileName]; + unset($preparedOutput['files'][$fileName]); + } + + return $preparedOutput; + } +}