diff --git a/RoboFile.php b/RoboFile.php index 945d03f..0e77d39 100644 --- a/RoboFile.php +++ b/RoboFile.php @@ -447,7 +447,7 @@ protected function getTaskPhpmdLint() { return $this ->taskPhpmdLintFiles() - ->addPathsFromFile('./rulesets/custom.include-pattern.txt') + ->setInputFile('./rulesets/custom.include-pattern.txt') ->addExcludePathsFromFile('./rulesets/custom.exclude-pattern.txt') ->setRuleSetFileNames(['custom']) ->setOutput($this->output()); diff --git a/composer.json b/composer.json index 4737eee..1151510 100644 --- a/composer.json +++ b/composer.json @@ -11,11 +11,13 @@ "require": { "php": ">=7.1", "consolidation/robo": "^1.0", - "phpmd/phpmd": "^2.6" + "phpmd/phpmd": "^2.6", + "symfony/process": "^3.2" }, "require-dev": { "codeception/codeception": "^2.2", "danielstjules/stringy": "^3.0", + "mikey179/vfsStream": "^1.6", "sweetchuck/codeception-module-robo-task-runner": "^0.0", "sweetchuck/git-hooks": "^0.0", "sweetchuck/robo-git": "^0.0", diff --git a/composer.lock b/composer.lock index 98cd2a8..d0c9bd8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "409910437c7997e0dbd7bf9e00bd24f7", + "content-hash": "002370b0395cb869356909a170b74bdc", "packages": [ { "name": "consolidation/annotated-command", @@ -1215,25 +1215,25 @@ }, { "name": "symfony/process", - "version": "v4.0.3", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "2145b3e8137e463b1051b79440a59b38220944f0" + "reference": "ff69f110c6b33fd33cd2089ba97d6112f44ef0ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/2145b3e8137e463b1051b79440a59b38220944f0", - "reference": "2145b3e8137e463b1051b79440a59b38220944f0", + "url": "https://api.github.com/repos/symfony/process/zipball/ff69f110c6b33fd33cd2089ba97d6112f44ef0ba", + "reference": "ff69f110c6b33fd33cd2089ba97d6112f44ef0ba", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": "^5.5.9|>=7.0.8" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -1260,7 +1260,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2018-01-03T07:38:00+00:00" + "time": "2018-01-03T07:37:34+00:00" }, { "name": "symfony/yaml", @@ -1823,6 +1823,52 @@ ], "time": "2017-03-20T17:10:46+00:00" }, + { + "name": "mikey179/vfsStream", + "version": "v1.6.5", + "source": { + "type": "git", + "url": "https://github.com/mikey179/vfsStream.git", + "reference": "d5fec95f541d4d71c4823bb5e30cf9b9e5b96145" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mikey179/vfsStream/zipball/d5fec95f541d4d71c4823bb5e30cf9b9e5b96145", + "reference": "d5fec95f541d4d71c4823bb5e30cf9b9e5b96145", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-0": { + "org\\bovigo\\vfs\\": "src/main/php" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Frank Kleine", + "homepage": "http://frankkleine.de/", + "role": "Developer" + } + ], + "description": "Virtual file system to mock the real file system in unit tests.", + "homepage": "http://vfs.bovigo.org/", + "time": "2017-08-01T08:02:14+00:00" + }, { "name": "myclabs/deep-copy", "version": "1.7.0", diff --git a/src/Task/PhpmdLintTask.php b/src/Task/PhpmdLintTask.php index e4ede04..9ab2d38 100644 --- a/src/Task/PhpmdLintTask.php +++ b/src/Task/PhpmdLintTask.php @@ -179,17 +179,6 @@ public function setPaths(array $value) return $this; } - - /** - * @return $this - */ - public function addPathsFromFile(string $fileName) - { - $lines = array_map('trim', file($fileName)); - $this->paths = array_fill_keys(array_filter($lines), true) + $this->paths; - - return $this; - } // endregion // region reportFormat @@ -576,7 +565,7 @@ public function setOptions(array $option) $this->setReportFile($value); break; - case 'reportFileHTML': + case 'reportFileHtml': $this->setReportFileHtml($value); break; @@ -837,7 +826,7 @@ protected function getCommandOptions(): array 'value' => $this->getInputFile(), ], 'coverage' => [ - 'type' => 'option:value', + 'type' => 'option:flag', 'value' => $this->getCoverage(), ], 'reportFile' => [ @@ -846,14 +835,17 @@ protected function getCommandOptions(): array ], 'reportFileHtml' => [ 'type' => 'option:value', + 'name' => 'reportfile-html', 'value' => $this->getReportFileHtml(), ], 'reportFileText' => [ 'type' => 'option:value', + 'name' => 'reportfile-text', 'value' => $this->getReportFileText(), ], 'reportFileXml' => [ 'type' => 'option:value', + 'name' => 'reportfile-xml', 'value' => $this->getReportFileXml(), ], 'suffixes' => [ diff --git a/tests/unit/Task/PhpmdTaskTest.php b/tests/unit/Task/PhpmdTaskTest.php index 1f35a38..bf8bb4c 100644 --- a/tests/unit/Task/PhpmdTaskTest.php +++ b/tests/unit/Task/PhpmdTaskTest.php @@ -3,7 +3,12 @@ namespace Sweetchuck\Robo\PhpMessDetector\Tests\Unit\Task; use Codeception\Test\Unit; +use Codeception\Util\Stub; +use org\bovigo\vfs\vfsStream; +use Robo\Robo; +use Sweetchuck\Codeception\Module\RoboTaskRunner\DummyProcess; use Sweetchuck\Robo\PhpMessDetector\Task\PhpmdLintFilesTask; +use Webmozart\PathUtil\Path; class PhpmdTaskTest extends Unit { @@ -24,7 +29,12 @@ public function casesGetCommand(): array "'html'", "'a.xml,c.xml'", "--minimumpriority '4'", + "--inputfile 'if.php'", + "--coverage", "--reportfile 'd.html'", + "--reportfile-html 'rf.html'", + "--reportfile-text 'rf.txt'", + "--reportfile-xml 'rf.xml'", "--suffixes 'php,inc'", "--exclude 'd.php,f.php'", '--strict', @@ -46,7 +56,12 @@ public function casesGetCommand(): array 'c.xml' => true, ], 'minimumPriority' => 4, + 'inputFile' => 'if.php', + 'coverage' => true, 'reportFile' => 'd.html', + 'reportFileHtml' => 'rf.html', + 'reportFileText' => 'rf.txt', + 'reportFileXml' => 'rf.xml', 'suffixes' => [ 'php' => true, 'phtml' => false, @@ -73,4 +88,134 @@ public function testGetCommand(string $expected, array $options) $task->setOptions($options); $this->tester->assertEquals($expected, $task->getCommand()); } + + public function testSuffixAddRemove() + { + $task = new PhpmdLintFilesTask(); + $task + ->setSuffixes(['a', 'b', 'c']) + ->removeSuffix('b') + ->addSuffix('d'); + $expected = [ + 'a' => true, + 'c' => true, + 'd' => true, + ]; + $this->tester->assertEquals($expected, $task->getSuffixes()); + } + + public function testExcludePaths() + { + $task = new PhpmdLintFilesTask(); + $task + ->setPhpmdExecutable('phpmd') + ->setExcludePaths(['a', 'b', 'c']) + ->removeExcludePath('b') + ->addExcludePath('d'); + + $this->tester->assertEquals( + ['a' => true, 'c' => true, 'd' => true], + $task->getExcludePaths() + ); + + $vfs = vfsStream::setup( + 'root', + 0777, + [ + __FUNCTION__ => [ + 'exclude-pattern.txt' => implode("\n", [ + 'src/', + 'a', + 'b', + '', + ]) + ] + ] + ); + + $fileName = $vfs->url() . '/' . __FUNCTION__ . '/exclude-pattern.txt'; + $task->addExcludePathsFromFile($fileName); + + $this->tester->assertEquals( + "phpmd 'text' --exclude 'src/,a,b,c,d'", + $task->getCommand() + ); + } + + public function casesRunSuccess(): array + { + $vfs = vfsStream::setup( + 'root', + 0777, + [ + __FUNCTION__ => [], + ] + ); + + return [ + 'basic' => [ + [ + 'exitCode' => 0, + ], + [ + 'workingDirectory' => $vfs->url(), + 'reportFile' => __FUNCTION__ . '/basic/foo/phpmd.txt', + ], + ], + ]; + } + + /** + * @dataProvider casesRunSuccess + */ + public function testRunSuccess(array $expected, array $options) + { + $container = Robo::createDefaultContainer(); + Robo::setContainer($container); + + /** @var \Sweetchuck\Robo\PhpMessDetector\Task\PhpmdLintFilesTask $task */ + $task = Stub::construct( + PhpmdLintFilesTask::class, + [], + [ + 'processClass' => DummyProcess::class, + ] + ); + $task->setOptions($options); + + $processIndex = count(DummyProcess::$instances); + DummyProcess::$prophecy[$processIndex] = [ + 'exitCode' => 0, + 'stdOutput' => '', + 'stdError' => '', + ]; + + $result = $task->run(); + + $this->tester->assertEquals( + $expected['exitCode'], + $result->getExitCode(), + 'Result "exitCode"' + ); + + $workingDirectory = $options['workingDirectory'] ?? '.'; + $reportFileOptions = [ + 'reportFile', + 'reportFileHtml', + 'reportFileText', + 'reportFileXml', + ]; + foreach ($reportFileOptions as $reportFileOption) { + if (empty($options[$reportFileOption])) { + continue; + } + + $fileName = Path::join($workingDirectory, $options[$reportFileOption]); + $dirName = Path::getDirectory($fileName); + $this->tester->assertFileExists( + $dirName, + "Directory is prepared for file; '$reportFileOption' = '$fileName'" + ); + } + } }