diff --git a/.gitignore b/.gitignore index 5b794ce..6f8cb49 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/build/ /composer.lock /.phpcheck/ /php_errors.log diff --git a/Makefile b/Makefile index 115de2d..e4b674e 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,12 @@ phpcheck: @phpcheck +phpcheck-coverage-html: + @phpcheck --coverage-html build/coverage + +phpcheck-coverage-text: + @phpcheck --coverage-text + phpcheck-no-defects: @phpcheck -d diff --git a/checks/GenCheck.php b/checks/GenCheck.php index e4178ff..d55c879 100644 --- a/checks/GenCheck.php +++ b/checks/GenCheck.php @@ -9,7 +9,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace Datashaman\PHPCheck\Checks; use Datashaman\PHPCheck\Check; diff --git a/composer.json b/composer.json index 5f6e70d..b9ee258 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,8 @@ }, "require-dev": { "friendsofphp/php-cs-fixer": "^2.14", - "phpmd/phpmd": "^2.6" + "phpmd/phpmd": "^2.6", + "phpunit/php-code-coverage": "^7.0" }, "config": { "platform": { diff --git a/src/ArgumentFactory.php b/src/ArgumentFactory.php index 2c4edaf..6ef74b4 100644 --- a/src/ArgumentFactory.php +++ b/src/ArgumentFactory.php @@ -9,7 +9,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace Datashaman\PHPCheck; use Exception; diff --git a/src/Check.php b/src/Check.php index 1b7ca96..ad7dcfe 100644 --- a/src/Check.php +++ b/src/Check.php @@ -9,7 +9,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace Datashaman\PHPCheck; class Check diff --git a/src/CheckCommand.php b/src/CheckCommand.php index f687c19..df42f5b 100644 --- a/src/CheckCommand.php +++ b/src/CheckCommand.php @@ -9,7 +9,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace Datashaman\PHPCheck; use Symfony\Component\Console\Command\Command; @@ -27,11 +26,13 @@ class CheckCommand extends Command protected function configure(): void { $this - ->setDescription('Runs checks.') - ->addOption('bootstrap', null, InputOption::VALUE_OPTIONAL, 'A PHP script that is included before the tests run') + ->setDescription('Run checks.') + ->addOption('bootstrap', null, InputOption::VALUE_OPTIONAL, 'A PHP script that is included before the checks run') + ->addOption('coverage-html', null, InputOption::VALUE_OPTIONAL, 'Generate code coverage report in HTML', false) + ->addOption('coverage-text', null, InputOption::VALUE_OPTIONAL, 'Generate code coverage report in text', false) ->addOption('filter', 'f', InputOption::VALUE_OPTIONAL, 'Filter the checks that will be run') ->addOption('iterations', 'i', InputOption::VALUE_REQUIRED, 'How many times each check will be run', Runner::MAX_ITERATIONS) - ->addOption('log-junit', 'j', InputOption::VALUE_OPTIONAL, 'Log test execution in JUnit XML format to file') + ->addOption('log-junit', 'j', InputOption::VALUE_OPTIONAL, 'Log check execution in JUnit XML format to file') ->addOption('no-defects', 'd', InputOption::VALUE_OPTIONAL, 'Ignore previous defects', false) ->addOption('seed', 's', InputOption::VALUE_OPTIONAL, 'Seed the random number generator to get repeatable runs') ->addArgument('path', InputArgument::OPTIONAL, 'File or folder with checks', 'checks'); diff --git a/src/CheckEvents.php b/src/CheckEvents.php index 326ab63..7455737 100644 --- a/src/CheckEvents.php +++ b/src/CheckEvents.php @@ -9,7 +9,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace Datashaman\PHPCheck; final class CheckEvents diff --git a/src/Events/EndAllEvent.php b/src/Events/EndAllEvent.php index 78bdeea..2584472 100644 --- a/src/Events/EndAllEvent.php +++ b/src/Events/EndAllEvent.php @@ -9,7 +9,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace Datashaman\PHPCheck\Events; class EndAllEvent extends Event diff --git a/src/Events/EndEvent.php b/src/Events/EndEvent.php index e57ab90..aac6a5e 100644 --- a/src/Events/EndEvent.php +++ b/src/Events/EndEvent.php @@ -9,7 +9,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace Datashaman\PHPCheck\Events; use ReflectionMethod; diff --git a/src/Events/ErrorEvent.php b/src/Events/ErrorEvent.php index a093fc8..4d78c6e 100644 --- a/src/Events/ErrorEvent.php +++ b/src/Events/ErrorEvent.php @@ -9,7 +9,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace Datashaman\PHPCheck\Events; class ErrorEvent extends ResultEvent diff --git a/src/Events/Event.php b/src/Events/Event.php index 204ec88..0fe52d7 100644 --- a/src/Events/Event.php +++ b/src/Events/Event.php @@ -9,7 +9,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace Datashaman\PHPCheck\Events; abstract class Event extends \Symfony\Component\EventDispatcher\Event diff --git a/src/Events/FailureEvent.php b/src/Events/FailureEvent.php index 9683ce1..fe29b63 100644 --- a/src/Events/FailureEvent.php +++ b/src/Events/FailureEvent.php @@ -9,7 +9,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace Datashaman\PHPCheck\Events; class FailureEvent extends ResultEvent diff --git a/src/Events/ResultEvent.php b/src/Events/ResultEvent.php index 4dca77b..490d633 100644 --- a/src/Events/ResultEvent.php +++ b/src/Events/ResultEvent.php @@ -9,7 +9,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace Datashaman\PHPCheck\Events; use ReflectionMethod; diff --git a/src/Events/StartAllEvent.php b/src/Events/StartAllEvent.php index 57f98e6..5e54eac 100644 --- a/src/Events/StartAllEvent.php +++ b/src/Events/StartAllEvent.php @@ -9,7 +9,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace Datashaman\PHPCheck\Events; class StartAllEvent extends Event diff --git a/src/Events/StartEvent.php b/src/Events/StartEvent.php index c389523..9f781c9 100644 --- a/src/Events/StartEvent.php +++ b/src/Events/StartEvent.php @@ -9,7 +9,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace Datashaman\PHPCheck\Events; use ReflectionMethod; diff --git a/src/Events/SuccessEvent.php b/src/Events/SuccessEvent.php index d1ee1c6..25ea0f0 100644 --- a/src/Events/SuccessEvent.php +++ b/src/Events/SuccessEvent.php @@ -9,7 +9,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace Datashaman\PHPCheck\Events; class SuccessEvent extends ResultEvent diff --git a/src/ExecutionError.php b/src/ExecutionError.php index 3f14b72..f1c8a2d 100644 --- a/src/ExecutionError.php +++ b/src/ExecutionError.php @@ -7,7 +7,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace Datashaman\PHPCheck; use Exception; diff --git a/src/ExecutionFailure.php b/src/ExecutionFailure.php index cc91a23..29369de 100644 --- a/src/ExecutionFailure.php +++ b/src/ExecutionFailure.php @@ -7,7 +7,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace Datashaman\PHPCheck; use Exception; diff --git a/src/Gen.php b/src/Gen.php index 3d52711..ae899b5 100644 --- a/src/Gen.php +++ b/src/Gen.php @@ -9,7 +9,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace Datashaman\PHPCheck; use Faker\Factory; diff --git a/src/Reporters/ConsoleReporter.php b/src/Reporters/ConsoleReporter.php index 246301b..d3df629 100644 --- a/src/Reporters/ConsoleReporter.php +++ b/src/Reporters/ConsoleReporter.php @@ -9,7 +9,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace Datashaman\PHPCheck\Reporters; use Datashaman\PHPCheck\CheckCommand; diff --git a/src/Reporters/HtmlCoverageReporter.php b/src/Reporters/HtmlCoverageReporter.php new file mode 100644 index 0000000..60e42a8 --- /dev/null +++ b/src/Reporters/HtmlCoverageReporter.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace Datashaman\PHPCheck\Reporters; + +use Datashaman\PHPCheck\CheckEvents; +use Datashaman\PHPCheck\Events; +use SebastianBergmann\CodeCoverage\CodeCoverage; +use SebastianBergmann\CodeCoverage\Report\Html\Facade as HtmlFacade; + +class HtmlCoverageReporter extends Reporter +{ + protected $coverage; + + public static function getSubscribedEvents(): array + { + return [ + CheckEvents::END => 'onEnd', + CheckEvents::END_ALL => 'onEndAll', + CheckEvents::START => 'onStart', + CheckEvents::START_ALL => 'onStartAll', + ]; + } + + public function onEnd(Events\EndEvent $event): void + { + $this->coverage->stop(); + } + + public function onEndAll(Events\EndAllEvent $event): void + { + $writer = new HtmlFacade(); + $writer->process($this->coverage, $this->input->getOption('coverage-html')); + } + + public function onStart(Events\StartEvent $event): void + { + $this->coverage->start($event->method->getName()); + } + + public function onStartAll(Events\StartAllEvent $event): void + { + if (!$this->input->getOption('coverage-html')) { + $this->output->writeln('You must specify a folder with --coverage-html'); + exit(1); + } + + $this->coverage = new CodeCoverage(); + $this->coverage->filter()->addDirectoryToWhitelist('./src'); + } +} diff --git a/src/Reporters/JUnitReporter.php b/src/Reporters/JUnitReporter.php index a31c19a..d4f6535 100644 --- a/src/Reporters/JUnitReporter.php +++ b/src/Reporters/JUnitReporter.php @@ -9,7 +9,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace Datashaman\PHPCheck\Reporters; use Datashaman\PHPCheck\CheckEvents; diff --git a/src/Reporters/Reporter.php b/src/Reporters/Reporter.php index d31e8b4..c7c28b1 100644 --- a/src/Reporters/Reporter.php +++ b/src/Reporters/Reporter.php @@ -9,7 +9,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace Datashaman\PHPCheck\Reporters; use Datashaman\PHPCheck\Runner; diff --git a/src/Reporters/TextCoverageReporter.php b/src/Reporters/TextCoverageReporter.php new file mode 100644 index 0000000..d2ed882 --- /dev/null +++ b/src/Reporters/TextCoverageReporter.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace Datashaman\PHPCheck\Reporters; + +use Datashaman\PHPCheck\CheckEvents; +use Datashaman\PHPCheck\Events; +use SebastianBergmann\CodeCoverage\CodeCoverage; +use SebastianBergmann\CodeCoverage\Report\Text; + +class TextCoverageReporter extends Reporter +{ + protected $coverage; + + public static function getSubscribedEvents(): array + { + return [ + CheckEvents::END => 'onEnd', + CheckEvents::END_ALL => 'onEndAll', + CheckEvents::START => 'onStart', + CheckEvents::START_ALL => 'onStartAll', + ]; + } + + public function onEnd(Events\EndEvent $event): void + { + $this->coverage->stop(); + } + + public function onEndAll(Events\EndAllEvent $event): void + { + $writer = new Text(); + + + if ($this->input->getOption('coverage-text')) { + $output = $writer->process($this->coverage, false); + file_put_contents($this->input->getOption('coverage-text'), $output); + + return; + } + + print $writer->process($this->coverage, true); + } + + public function onStart(Events\StartEvent $event): void + { + $this->coverage->start($event->method->getName()); + } + + public function onStartAll(Events\StartAllEvent $event): void + { + $this->coverage = new CodeCoverage(); + $this->coverage->filter()->addDirectoryToWhitelist('./src'); + } +} diff --git a/src/RunState.php b/src/RunState.php index d840b6d..fab33cb 100644 --- a/src/RunState.php +++ b/src/RunState.php @@ -7,7 +7,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace Datashaman\PHPCheck; use ReflectionMethod; diff --git a/src/Runner.php b/src/Runner.php index db22956..c996e4a 100644 --- a/src/Runner.php +++ b/src/Runner.php @@ -9,7 +9,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace Datashaman\PHPCheck; use InvalidArgumentException; @@ -148,6 +147,14 @@ public function execute(InputInterface $input, OutputInterface $output): void $this->dispatcher->addSubscriber(new Reporters\ConsoleReporter($this)); + if ($input->getOption('coverage-html') !== false) { + $this->dispatcher->addSubscriber(new Reporters\HtmlCoverageReporter($this)); + } + + if ($input->getOption('coverage-text') !== false) { + $this->dispatcher->addSubscriber(new Reporters\TextCoverageReporter($this)); + } + if ($input->getOption('log-junit')) { $reporter = new Reporters\JUnitReporter($this); $this->dispatcher->addSubscriber($reporter);