diff --git a/.ci/travis-functions.sh b/.ci/travis-functions.sh index 98a9a1d8b..3a80314b6 100644 --- a/.ci/travis-functions.sh +++ b/.ci/travis-functions.sh @@ -32,4 +32,4 @@ function get-infection-pr-flags() { fi echo $INFECTION_PR_FLAGS; -} \ No newline at end of file +} diff --git a/src/Command/InfectionCommand.php b/src/Command/InfectionCommand.php index 4a8cace01..fcc82a668 100644 --- a/src/Command/InfectionCommand.php +++ b/src/Command/InfectionCommand.php @@ -120,6 +120,12 @@ protected function configure(): void InputOption::VALUE_NONE, 'Show mutations to the console' ) + ->addOption( + 'no-progress', + null, + InputOption::VALUE_NONE, + 'Do not output progress bars' + ) ->addOption( 'configuration', 'c', diff --git a/src/Process/Builder/SubscriberBuilder.php b/src/Process/Builder/SubscriberBuilder.php index 371e34f57..58e1eeaa4 100644 --- a/src/Process/Builder/SubscriberBuilder.php +++ b/src/Process/Builder/SubscriberBuilder.php @@ -41,11 +41,15 @@ use Infection\Console\OutputFormatter\ProgressFormatter; use Infection\Differ\DiffColorizer; use Infection\EventDispatcher\EventDispatcherInterface; +use Infection\EventDispatcher\EventSubscriberInterface; use Infection\Mutant\MetricsCalculator; use Infection\Performance\Listener\PerformanceLoggerSubscriber; use Infection\Performance\Memory\MemoryFormatter; use Infection\Performance\Time\TimeFormatter; use Infection\Performance\Time\Timer; +use Infection\Process\Listener\CiInitialTestsConsoleLoggerSubscriber; +use Infection\Process\Listener\CiMutantCreatingConsoleLoggerSubscriber; +use Infection\Process\Listener\CiMutationGeneratingConsoleLoggerSubscriber; use Infection\Process\Listener\CleanUpAfterMutationTestingFinishedSubscriber; use Infection\Process\Listener\InitialTestsConsoleLoggerSubscriber; use Infection\Process\Listener\MutantCreatingConsoleLoggerSubscriber; @@ -150,9 +154,9 @@ private function getSubscribers( OutputInterface $output ): array { $subscribers = [ - new InitialTestsConsoleLoggerSubscriber($output, $testFrameworkAdapter), - new MutationGeneratingConsoleLoggerSubscriber($output), - new MutantCreatingConsoleLoggerSubscriber($output), + $this->getInitialTestsConsoleLoggerSubscriber($testFrameworkAdapter, $output), + $this->getMutantGeneratingConsoleLoggerSubscriber($output), + $this->getMutantCreatingConsoleLoggerSubscriber($output), new MutationTestingConsoleLoggerSubscriber( $output, $this->getOutputFormatter($output), @@ -199,4 +203,38 @@ private function getOutputFormatter(OutputInterface $output): OutputFormatter throw new \InvalidArgumentException('Incorrect formatter. Possible values: "dot", "progress"'); } + + private function getMutantCreatingConsoleLoggerSubscriber(OutputInterface $output): EventSubscriberInterface + { + if ($this->shouldSkipProgressBars()) { + return new CiMutantCreatingConsoleLoggerSubscriber($output); + } + + return new MutantCreatingConsoleLoggerSubscriber($output); + } + + private function getMutantGeneratingConsoleLoggerSubscriber(OutputInterface $output): EventSubscriberInterface + { + if ($this->shouldSkipProgressBars()) { + return new CiMutationGeneratingConsoleLoggerSubscriber($output); + } + + return new MutationGeneratingConsoleLoggerSubscriber($output); + } + + private function getInitialTestsConsoleLoggerSubscriber(AbstractTestFrameworkAdapter $testFrameworkAdapter, OutputInterface $output): EventSubscriberInterface + { + if ($this->shouldSkipProgressBars()) { + return new CiInitialTestsConsoleLoggerSubscriber($output, $testFrameworkAdapter); + } + + return new InitialTestsConsoleLoggerSubscriber($output, $testFrameworkAdapter); + } + + private function shouldSkipProgressBars(): bool + { + return $this->input->getOption('no-progress') + || getenv('CI') === 'true' + || getenv('CONTINUOUS_INTEGRATION') === 'true'; + } } diff --git a/src/Process/Listener/CiInitialTestsConsoleLoggerSubscriber.php b/src/Process/Listener/CiInitialTestsConsoleLoggerSubscriber.php new file mode 100644 index 000000000..b41a89658 --- /dev/null +++ b/src/Process/Listener/CiInitialTestsConsoleLoggerSubscriber.php @@ -0,0 +1,89 @@ +output = $output; + $this->testFrameworkAdapter = $testFrameworkAdapter; + } + + public function getSubscribedEvents(): array + { + return [ + InitialTestSuiteStarted::class => [$this, 'onInitialTestSuiteStarted'], + ]; + } + + public function onInitialTestSuiteStarted(InitialTestSuiteStarted $event): void + { + try { + $version = $this->testFrameworkAdapter->getVersion(); + } catch (\InvalidArgumentException $e) { + $version = 'unknown'; + } + + $this->output->writeln([ + 'Running initial test suite...', + '', + sprintf( + '%s version: %s', + $this->testFrameworkAdapter->getName(), + $version + ), + ]); + } +} diff --git a/src/Process/Listener/CiMutantCreatingConsoleLoggerSubscriber.php b/src/Process/Listener/CiMutantCreatingConsoleLoggerSubscriber.php new file mode 100644 index 000000000..ca7acb38d --- /dev/null +++ b/src/Process/Listener/CiMutantCreatingConsoleLoggerSubscriber.php @@ -0,0 +1,71 @@ +output = $output; + } + + public function getSubscribedEvents(): array + { + return [ + MutantsCreatingStarted::class => [$this, 'onMutantsCreatingStarted'], + ]; + } + + public function onMutantsCreatingStarted(MutantsCreatingStarted $event): void + { + $this->output->writeln([ + '', + sprintf('Creating mutated files and processes: %s', $event->getMutantCount()), + ]); + } +} diff --git a/src/Process/Listener/CiMutationGeneratingConsoleLoggerSubscriber.php b/src/Process/Listener/CiMutationGeneratingConsoleLoggerSubscriber.php new file mode 100644 index 000000000..7ba06c1ac --- /dev/null +++ b/src/Process/Listener/CiMutationGeneratingConsoleLoggerSubscriber.php @@ -0,0 +1,73 @@ +output = $output; + } + + public function getSubscribedEvents(): array + { + return [ + MutationGeneratingStarted::class => [$this, 'onMutationGeneratingStarted'], + ]; + } + + public function onMutationGeneratingStarted(MutationGeneratingStarted $event): void + { + $this->output->writeln([ + '', + 'Generate mutants...', + '', + sprintf('Processing source code files: %s', $event->getMutableFilesCount()), + ]); + } +} diff --git a/src/TestFramework/AbstractTestFrameworkAdapter.php b/src/TestFramework/AbstractTestFrameworkAdapter.php index f15002d56..0efe0a4a5 100644 --- a/src/TestFramework/AbstractTestFrameworkAdapter.php +++ b/src/TestFramework/AbstractTestFrameworkAdapter.php @@ -198,7 +198,7 @@ public function getVersion(): string $process->mustRun(); - $version = null; + $version = 'unknown'; try { $version = $this->versionParser->parse($process->getOutput()); diff --git a/tests/Console/E2ETest.php b/tests/Console/E2ETest.php index ad792c591..d2bf4c224 100644 --- a/tests/Console/E2ETest.php +++ b/tests/Console/E2ETest.php @@ -67,6 +67,10 @@ final class E2ETest extends TestCase protected function setUp(): void { + if (\PHP_SAPI === 'phpdbg') { + $this->markTestSkipped('Running this test on PHPDBG causes failures on Travis, see https://github.com/infection/infection/pull/622.'); + } + // Without overcommit this test fails with `proc_open(): fork failed - Cannot allocate memory` if (strpos(PHP_OS, 'Linux') === 0 && is_readable('/proc/sys/vm/overcommit_memory') && diff --git a/tests/Process/Builder/SubscriberBuilderTest.php b/tests/Process/Builder/SubscriberBuilderTest.php index b2955a786..66a34b6be 100644 --- a/tests/Process/Builder/SubscriberBuilderTest.php +++ b/tests/Process/Builder/SubscriberBuilderTest.php @@ -57,10 +57,11 @@ final class SubscriberBuilderTest extends TestCase public function test_it_registers_the_subscribers_when_debugging(): void { $input = $this->createMock(InputInterface::class); - $input->expects($this->exactly(6)) + $input->expects($this->exactly(9)) ->method('getOption') ->will($this->returnValueMap( [ + ['ci-friendly', false], ['formatter', 'progress'], ['show-mutations', true], ['log-verbosity', 'all'], @@ -94,10 +95,11 @@ public function test_it_registers_the_subscribers_when_debugging(): void public function test_it_registers_the_subscribers_when_not_debugging(): void { $input = $this->createMock(InputInterface::class); - $input->expects($this->exactly(6)) + $input->expects($this->exactly(9)) ->method('getOption') ->will($this->returnValueMap( [ + ['ci-friendly', false], ['formatter', 'progress'], ['show-mutations', true], ['log-verbosity', 'all'], @@ -131,10 +133,11 @@ public function test_it_registers_the_subscribers_when_not_debugging(): void public function test_it_throws_an_exception_when_output_formatter_is_invalid(): void { $input = $this->createMock(InputInterface::class); - $input->expects($this->exactly(2)) + $input->expects($this->exactly(5)) ->method('getOption') ->will($this->returnValueMap( [ + ['ci-friendly', false], ['formatter', 'foo'], ['show-mutations', true], ] diff --git a/tests/Process/Listener/CiInitialTestsConsoleLoggerSubscriberTest.php b/tests/Process/Listener/CiInitialTestsConsoleLoggerSubscriberTest.php new file mode 100644 index 000000000..f7fd13d0b --- /dev/null +++ b/tests/Process/Listener/CiInitialTestsConsoleLoggerSubscriberTest.php @@ -0,0 +1,92 @@ +output = $this->createMock(OutputInterface::class); + $this->testFramework = $this->createMock(AbstractTestFrameworkAdapter::class); + } + + public function test_it_reacts_on_mutants_creating_event(): void + { + $this->output->expects($this->once()) + ->method('writeln') + ->with([ + 'Running initial test suite...', + '', + 'PHPUnit version: 6.5.4', + ]); + + $this->testFramework->expects($this->once()) + ->method('getVersion') + ->willReturn('6.5.4'); + + $this->testFramework->expects($this->once()) + ->method('getName') + ->willReturn('PHPUnit'); + + $dispatcher = new EventDispatcher(); + $dispatcher->addSubscriber(new CiInitialTestsConsoleLoggerSubscriber($this->output, $this->testFramework)); + + $dispatcher->dispatch(new InitialTestSuiteStarted()); + } +} diff --git a/tests/Process/Listener/CiMutantCreatingConsoleLoggerSubscriberTest.php b/tests/Process/Listener/CiMutantCreatingConsoleLoggerSubscriberTest.php new file mode 100644 index 000000000..8e26db5f8 --- /dev/null +++ b/tests/Process/Listener/CiMutantCreatingConsoleLoggerSubscriberTest.php @@ -0,0 +1,76 @@ +output = $this->createMock(OutputInterface::class); + } + + public function test_it_reacts_on_mutants_creating_event(): void + { + $this->output->expects($this->once()) + ->method('writeln') + ->with([ + '', + 'Creating mutated files and processes: 123', + ]); + + $dispatcher = new EventDispatcher(); + $dispatcher->addSubscriber(new CiMutantCreatingConsoleLoggerSubscriber($this->output)); + + $dispatcher->dispatch(new MutantsCreatingStarted(123)); + } +} diff --git a/tests/Process/Listener/CiMutationGeneratingConsoleLoggerSubscriberTest.php b/tests/Process/Listener/CiMutationGeneratingConsoleLoggerSubscriberTest.php new file mode 100644 index 000000000..d1fd2b9a2 --- /dev/null +++ b/tests/Process/Listener/CiMutationGeneratingConsoleLoggerSubscriberTest.php @@ -0,0 +1,78 @@ +output = $this->createMock(OutputInterface::class); + } + + public function test_it_reacts_on_mutation_generating_started_event(): void + { + $this->output->expects($this->once()) + ->method('writeln') + ->with([ + '', + 'Generate mutants...', + '', + 'Processing source code files: 123', + ]); + + $dispatcher = new EventDispatcher(); + $dispatcher->addSubscriber(new CiMutationGeneratingConsoleLoggerSubscriber($this->output)); + + $dispatcher->dispatch(new MutationGeneratingStarted(123)); + } +}