diff --git a/Makefile b/Makefile index 35386d75..a8e20cdd 100644 --- a/Makefile +++ b/Makefile @@ -68,7 +68,7 @@ package: tools/box sed -e 's/Application('"'"'dev/Application('"'"'$(TOOLBOX_VERSION)/g' bin/toolbox.php > build/phar/bin/toolbox.php cd build/phar && \ - composer config platform.php 8.0.0 && \ + composer config platform.php 8.0.2 && \ composer update --no-dev -o -a tools/box compile @@ -84,7 +84,7 @@ package-devkit: tools/box sed -e 's/\(Application(.*\)'"'"'dev/\1'"'"'$(TOOLBOX_VERSION)/g' bin/devkit.php > build/devkit-phar/bin/devkit.php cd build/devkit-phar && \ - composer config platform.php 8.0.0 && \ + composer config platform.php 8.0.2 && \ composer update --no-dev -o -a tools/box compile -c box-devkit.json.dist diff --git a/composer.json b/composer.json index 5782f260..978cb7f6 100644 --- a/composer.json +++ b/composer.json @@ -3,14 +3,13 @@ "description": "Helps to discover and install tools", "type": "project", "require": { - "php": "~8.0.0 || ~8.1.0 || ~8.2.0", - "symfony/console": "^4.4 || ^5.4 || ^6.1", - "psr/container": "^1.0" + "php": "~8.0.2 || ~8.1.0 || ~8.2.0", + "symfony/console": "^5.4.31 || ^6.3", + "psr/container": "^2.0" }, "require-dev": { "phpunit/phpunit": "^9.5", "zalas/phpunit-globals": "^2.1", - "phpspec/prophecy-phpunit": "^2.0", "infection/infection": "^0.26" }, "autoload": { diff --git a/src/Cli/ServiceContainer.php b/src/Cli/ServiceContainer.php index 1cd3d9f5..11996ec7 100644 --- a/src/Cli/ServiceContainer.php +++ b/src/Cli/ServiceContainer.php @@ -51,7 +51,7 @@ public function set(string $id, /*object */$service): void /** * {@inheritdoc} */ - public function get($id) + public function get(string $id) { if (isset($this->runtimeServices[$id])) { return $this->runtimeServices[$id]; @@ -68,7 +68,7 @@ public function get($id) /** * {@inheritdoc} */ - public function has($id) + public function has(string $id): bool { return isset($this->services[$id]) || isset($this->runtimeServices[$id]); } diff --git a/tests/Cli/ApplicationTest.php b/tests/Cli/ApplicationTest.php index e5ed3960..975b240a 100644 --- a/tests/Cli/ApplicationTest.php +++ b/tests/Cli/ApplicationTest.php @@ -2,10 +2,8 @@ namespace Zalas\Toolbox\Tests\Cli; +use PHPUnit\Framework\MockObject\Stub; use PHPUnit\Framework\TestCase; -use Prophecy\Argument; -use Prophecy\PhpUnit\ProphecyTrait; -use Prophecy\Prophecy\ObjectProphecy; use Symfony\Component\Console\Application as CliApplication; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Output\NullOutput; @@ -17,8 +15,6 @@ class ApplicationTest extends TestCase { - use ProphecyTrait; - private const VERSION = 'test'; /** @@ -27,14 +23,14 @@ class ApplicationTest extends TestCase private $app; /** - * @var ServiceContainer|ObjectProphecy + * @var ServiceContainer|Stub */ private $container; protected function setUp(): void { - $this->container = $this->prophesize(ServiceContainer::class); - $this->app = new Application(self::VERSION, $this->container->reveal()); + $this->container = $this->createStub(ServiceContainer::class); + $this->app = new Application(self::VERSION, $this->container); } public function test_it_is_a_cli_application() @@ -113,7 +109,7 @@ public function test_it_allows_to_override_tools_location() */ public function test_it_runs_the_command_in_dry_run_mode() { - $output = $this->prophesize(OutputInterface::class); + $output = $this->givenOutputThatExpectsMessageWritten('composer global bin phpstan require'); $app = new Application(self::VERSION, new ServiceContainer()); $app->doRun( @@ -123,12 +119,17 @@ public function test_it_runs_the_command_in_dry_run_mode() '--tools' => [__DIR__.'/../resources/tools.json'], '--no-interaction' => true, ]), - $output->reveal() + $output ); + } + + public function givenOutputThatExpectsMessageWritten(string $message): OutputInterface + { + $output = $this->createMock(OutputInterface::class); + $output->expects(self::once()) + ->method('writeln') + ->with(self::stringContains($message)); - $output->writeln(Argument::allOf( - Argument::type('string'), - Argument::containingString('composer global bin phpstan require') - ))->shouldHaveBeenCalled(); + return $output; } } diff --git a/tests/Cli/Command/InstallCommandTest.php b/tests/Cli/Command/InstallCommandTest.php index 20c8b20a..4d4a5e2d 100644 --- a/tests/Cli/Command/InstallCommandTest.php +++ b/tests/Cli/Command/InstallCommandTest.php @@ -2,35 +2,32 @@ namespace Zalas\Toolbox\Tests\Cli\Command; -use Prophecy\Argument; -use Prophecy\PhpUnit\ProphecyTrait; -use Prophecy\Prophecy\ObjectProphecy; +use PHPUnit\Framework\MockObject\Stub; use Zalas\Toolbox\Cli\Command\InstallCommand; use Zalas\Toolbox\Runner\Runner; use Zalas\Toolbox\Tool\Command; +use Zalas\Toolbox\Tool\Command\ShCommand; use Zalas\Toolbox\Tool\Filter; use Zalas\Toolbox\UseCase\InstallTools; class InstallCommandTest extends ToolboxCommandTestCase { - use ProphecyTrait; - protected const CLI_COMMAND_NAME = InstallCommand::NAME; /** - * @var Runner|ObjectProphecy + * @var Runner|Stub */ private $runner; /** - * @var InstallTools|ObjectProphecy + * @var InstallTools|Stub */ private $useCase; protected function setUp(): void { - $this->runner = $this->prophesize(Runner::class); - $this->useCase = $this->prophesize(InstallTools::class); + $this->runner = $this->createStub(Runner::class); + $this->useCase = $this->createStub(InstallTools::class); parent::setUp(); } @@ -38,20 +35,18 @@ protected function setUp(): void public function test_it_runs_the_install_tools_use_case() { $command = $this->createCommand(); - $this->useCase->__invoke(Argument::type(Filter::class))->willReturn($command); - $this->runner->run($command)->willReturn(0); + $this->useCase->method('__invoke')->willReturn($command); + $this->runner->method('run')->with($command)->willReturn(0); $tester = $this->executeCliCommand(); - $this->runner->run($command)->shouldHaveBeenCalled(); - $this->assertSame(0, $tester->getStatusCode()); } public function test_it_returns_the_status_code_of_the_run() { - $this->useCase->__invoke(Argument::type(Filter::class))->willReturn($this->createCommand()); - $this->runner->run(Argument::any())->willReturn(1); + $this->useCase->method('__invoke')->willReturn($this->createCommand()); + $this->runner->method('run')->willReturn(1); $tester = $this->executeCliCommand(); @@ -60,12 +55,15 @@ public function test_it_returns_the_status_code_of_the_run() public function test_it_filters_by_tags() { - $this->useCase->__invoke(Argument::type(Filter::class))->willReturn($this->createCommand()); - $this->runner->run(Argument::any())->willReturn(0); + $this->useCase + ->method('__invoke') + ->with(new Filter(['foo'], ['bar'])) + ->willReturn($this->createCommand()); + $this->runner->method('run')->willReturn(0); - $this->executeCliCommand(['--exclude-tag' => ['foo'], '--tag' => ['bar']]); + $tester = $this->executeCliCommand(['--exclude-tag' => ['foo'], '--tag' => ['bar']]); - $this->useCase->__invoke(new Filter(['foo'], ['bar']))->shouldBeCalled(); + $this->assertSame(0, $tester->getStatusCode()); } public function test_it_defines_dry_run_option() @@ -118,16 +116,13 @@ public function test_it_takes_the_tag_option_default_from_environment_if_present protected function getContainerTestDoubles(): array { return [ - Runner::class => $this->runner->reveal(), - InstallTools::class => $this->useCase->reveal(), + Runner::class => $this->runner, + InstallTools::class => $this->useCase, ]; } private function createCommand(): Command { - $command = $this->prophesize(Command::class); - $command->__toString()->willReturn('echo "foo"'); - - return $command->reveal(); + return new ShCommand('echo "foo"'); } } diff --git a/tests/Cli/Command/ListCommandTest.php b/tests/Cli/Command/ListCommandTest.php index a45be286..a44eeea4 100644 --- a/tests/Cli/Command/ListCommandTest.php +++ b/tests/Cli/Command/ListCommandTest.php @@ -2,36 +2,34 @@ namespace Zalas\Toolbox\Tests\Cli\Command; -use Prophecy\Argument; -use Prophecy\PhpUnit\ProphecyTrait; -use Prophecy\Prophecy\ObjectProphecy; +use PHPUnit\Framework\MockObject\Stub; use Zalas\Toolbox\Cli\Command\ListCommand; use Zalas\Toolbox\Tool\Collection; +use Zalas\Toolbox\Tool\Command\ShCommand; +use Zalas\Toolbox\Tool\Command\TestCommand; use Zalas\Toolbox\Tool\Filter; use Zalas\Toolbox\Tool\Tool; use Zalas\Toolbox\UseCase\ListTools; class ListCommandTest extends ToolboxCommandTestCase { - use ProphecyTrait; - protected const CLI_COMMAND_NAME = ListCommand::NAME; /** - * @var ListTools|ObjectProphecy + * @var ListTools|Stub */ private $useCase; protected function setUp(): void { - $this->useCase = $this->prophesize(ListTools::class); + $this->useCase = $this->createStub(ListTools::class); parent::setUp(); } public function test_it_runs_the_list_tools_use_case() { - $this->useCase->__invoke(Argument::type(Filter::class))->willReturn(Collection::create([ + $this->useCase->method('__invoke')->willReturn(Collection::create([ $this->createTool('Behat', 'Tests business expectations', 'http://behat.org'), ])); @@ -44,13 +42,15 @@ public function test_it_runs_the_list_tools_use_case() public function test_it_filters_by_tags() { - $this->useCase->__invoke(Argument::type(Filter::class))->willReturn(Collection::create([ - $this->createTool('Behat', 'Tests business expectations', 'http://behat.org'), - ])); + $this->useCase->method('__invoke') + ->with(new Filter(['foo'], ['bar'])) + ->willReturn(Collection::create([ + $this->createTool('Behat', 'Tests business expectations', 'http://behat.org'), + ])); - $this->executeCliCommand(['--exclude-tag' => ['foo'], '--tag' => ['bar']]); + $tester = $this->executeCliCommand(['--exclude-tag' => ['foo'], '--tag' => ['bar']]); - $this->useCase->__invoke(new Filter(['foo'], ['bar']))->shouldHaveBeenCalled(); + $this->assertSame(0, $tester->getStatusCode()); } public function test_it_defines_exclude_tag_option() @@ -83,17 +83,19 @@ public function test_it_takes_the_tag_option_default_from_environment_if_present protected function getContainerTestDoubles(): array { return [ - ListTools::class => $this->useCase->reveal(), + ListTools::class => $this->useCase, ]; } private function createTool(string $name, string $summary, string $website): Tool { - $tool = $this->prophesize(Tool::class); - $tool->name()->willReturn($name); - $tool->summary()->willReturn($summary); - $tool->website()->willReturn($website); - - return $tool->reveal(); + return new Tool( + $name, + $summary, + $website, + [], + new ShCommand('any command'), + new TestCommand('any test command', 'any') + ); } } diff --git a/tests/Cli/Command/TestCommandTest.php b/tests/Cli/Command/TestCommandTest.php index 43ee76fc..be6fb590 100644 --- a/tests/Cli/Command/TestCommandTest.php +++ b/tests/Cli/Command/TestCommandTest.php @@ -2,35 +2,32 @@ namespace Zalas\Toolbox\Tests\Cli\Command; -use Prophecy\Argument; -use Prophecy\PhpUnit\ProphecyTrait; -use Prophecy\Prophecy\ObjectProphecy; +use PHPUnit\Framework\MockObject\Stub; use Zalas\Toolbox\Cli\Command\TestCommand; use Zalas\Toolbox\Runner\Runner; use Zalas\Toolbox\Tool\Command; +use Zalas\Toolbox\Tool\Command\ShCommand; use Zalas\Toolbox\Tool\Filter; use Zalas\Toolbox\UseCase\TestTools; class TestCommandTest extends ToolboxCommandTestCase { - use ProphecyTrait; - protected const CLI_COMMAND_NAME = TestCommand::NAME; /** - * @var Runner|ObjectProphecy + * @var Runner|Stub */ private $runner; /** - * @var TestTools|ObjectProphecy + * @var TestTools|Stub */ private $useCase; protected function setUp(): void { - $this->runner = $this->prophesize(Runner::class); - $this->useCase = $this->prophesize(TestTools::class); + $this->runner = $this->createStub(Runner::class); + $this->useCase = $this->createStub(TestTools::class); parent::setUp(); } @@ -38,20 +35,18 @@ protected function setUp(): void public function test_it_runs_the_test_tools_use_case() { $command = $this->createCommand(); - $this->useCase->__invoke(Argument::type(Filter::class))->willReturn($command); - $this->runner->run($command)->willReturn(0); + $this->useCase->method('__invoke')->willReturn($command); + $this->runner->method('run')->with($command)->willReturn(0); $tester = $this->executeCliCommand(); - $this->runner->run($command)->shouldHaveBeenCalled(); - $this->assertSame(0, $tester->getStatusCode()); } public function test_it_returns_the_status_code_of_the_run() { - $this->useCase->__invoke(Argument::type(Filter::class))->willReturn($this->createCommand()); - $this->runner->run(Argument::any())->willReturn(1); + $this->useCase->method('__invoke')->willReturn($this->createCommand()); + $this->runner->method('run')->willReturn(1); $tester = $this->executeCliCommand(); @@ -60,12 +55,12 @@ public function test_it_returns_the_status_code_of_the_run() public function test_it_filters_by_tags() { - $this->useCase->__invoke(Argument::type(Filter::class))->willReturn($this->createCommand()); - $this->runner->run(Argument::any())->willReturn(0); + $this->useCase->method('__invoke')->with(new Filter(['foo'], ['bar']))->willReturn($this->createCommand()); + $this->runner->method('run')->willReturn(0); - $this->executeCliCommand(['--exclude-tag' => ['foo'], '--tag' => ['bar']]); + $tester = $this->executeCliCommand(['--exclude-tag' => ['foo'], '--tag' => ['bar']]); - $this->useCase->__invoke(new Filter(['foo'], ['bar']))->shouldBeCalled(); + $this->assertSame(0, $tester->getStatusCode()); } public function test_it_defines_dry_run_option() @@ -117,16 +112,13 @@ public function test_it_takes_the_tag_option_default_from_environment_if_present protected function getContainerTestDoubles(): array { return [ - Runner::class => $this->runner->reveal(), - TestTools::class => $this->useCase->reveal(), + Runner::class => $this->runner, + TestTools::class => $this->useCase, ]; } private function createCommand(): Command { - $command = $this->prophesize(Command::class); - $command->__toString()->willReturn('true'); - - return $command->reveal(); + return new ShCommand('true'); } } diff --git a/tests/Cli/Runner/DryRunnerTest.php b/tests/Cli/Runner/DryRunnerTest.php index a0f20a4f..032ea609 100644 --- a/tests/Cli/Runner/DryRunnerTest.php +++ b/tests/Cli/Runner/DryRunnerTest.php @@ -2,9 +2,8 @@ namespace Zalas\Toolbox\Tests\Cli\Runner; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use Prophecy\PhpUnit\ProphecyTrait; -use Prophecy\Prophecy\ObjectProphecy; use Symfony\Component\Console\Output\OutputInterface; use Zalas\Toolbox\Cli\Runner\DryRunner; use Zalas\Toolbox\Runner\Runner; @@ -12,22 +11,20 @@ class DryRunnerTest extends TestCase { - use ProphecyTrait; - /** * @var DryRunner */ private $runner; /** - * @var OutputInterface|ObjectProphecy + * @var OutputInterface|MockObject */ private $out; protected function setUp(): void { - $this->out = $this->prophesize(OutputInterface::class); - $this->runner = new DryRunner($this->out->reveal()); + $this->out = $this->createMock(OutputInterface::class); + $this->runner = new DryRunner($this->out); } public function test_it_is_a_runner() @@ -37,6 +34,10 @@ public function test_it_is_a_runner() public function test_it_sends_the_command_to_the_output() { + $this->out->expects(self::once()) + ->method('writeln') + ->with('echo "Foo"'); + $result = $this->runner->run(new class implements Command { public function __toString(): string { @@ -44,8 +45,6 @@ public function __toString(): string } }); - $this->out->writeln('echo "Foo"')->shouldHaveBeenCalled(); - $this->assertSame(0, $result); } } diff --git a/tests/Cli/ServiceContainer/LazyRunnerTest.php b/tests/Cli/ServiceContainer/LazyRunnerTest.php index 6c533735..4144b012 100644 --- a/tests/Cli/ServiceContainer/LazyRunnerTest.php +++ b/tests/Cli/ServiceContainer/LazyRunnerTest.php @@ -2,9 +2,8 @@ namespace Zalas\Toolbox\Tests\Cli\ServiceContainer; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use Prophecy\PhpUnit\ProphecyTrait; -use Prophecy\Prophecy\ObjectProphecy; use Zalas\Toolbox\Cli\ServiceContainer\LazyRunner; use Zalas\Toolbox\Cli\ServiceContainer\RunnerFactory; use Zalas\Toolbox\Runner\Runner; @@ -12,59 +11,68 @@ class LazyRunnerTest extends TestCase { - use ProphecyTrait; - /** * @var LazyRunner */ - private $runner; + private $lazyRunner; /** - * @var RunnerFactory|ObjectProphecy + * @var RunnerFactory|MockObject */ private $factory; protected function setUp(): void { - $this->factory = $this->prophesize(RunnerFactory::class); + $this->factory = $this->createMock(RunnerFactory::class); - $this->runner = new LazyRunner($this->factory->reveal()); + $this->lazyRunner = new LazyRunner($this->factory); } public function test_it_is_a_runner() { - $this->assertInstanceOf(Runner::class, $this->runner); + $this->assertInstanceOf(Runner::class, $this->lazyRunner); } public function test_it_returns_status_code_of_returned_by_the_created_runner() { $command = $this->command(); - $runner = $this->prophesize(Runner::class); - $runner->run($command)->willReturn(1); - - $this->factory->createRunner()->willReturn($runner); + $runner = $this->givenRunner(command: $command, result: 1); + $this->givenFactoryCreates($runner); - $this->assertSame(1, $this->runner->run($command)); + $this->assertSame(1, $this->lazyRunner->run($command)); } public function test_it_only_initializes_the_runner_once() { $command = $this->command(); - $runner = $this->prophesize(Runner::class); - $runner->run($command)->willReturn(0); + $runner = $this->givenRunner($command, 0); - $this->factory->createRunner()->willReturn($runner); + $this->factory + ->expects(self::once()) + ->method('createRunner') + ->willReturn($runner); + + $this->lazyRunner->run($command); + $this->lazyRunner->run($command); + } - $this->runner->run($command); - $this->runner->run($command); + public function givenRunner(Command $command, int $result): Runner + { + $runner = $this->createStub(Runner::class); + $runner->method('run')->with($command)->willReturn($result); - $this->factory->createRunner()->shouldHaveBeenCalledTimes(1); + return $runner; } private function command(): Command { - return $this->prophesize(Command::class)->reveal(); + return new Command\ShCommand('any command'); + } + + private function givenFactoryCreates(Runner $runner): void + { + $this->factory->method('createRunner')->willReturn($runner); } } diff --git a/tests/Cli/ServiceContainer/RunnerFactoryTest.php b/tests/Cli/ServiceContainer/RunnerFactoryTest.php index 0d415504..22860d1f 100644 --- a/tests/Cli/ServiceContainer/RunnerFactoryTest.php +++ b/tests/Cli/ServiceContainer/RunnerFactoryTest.php @@ -2,12 +2,14 @@ namespace Zalas\Toolbox\Tests\Cli\ServiceContainer; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use Prophecy\PhpUnit\ProphecyTrait; -use Prophecy\Prophecy\ObjectProphecy; use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; +use Symfony\Component\Console\Input\ArrayInput; +use Symfony\Component\Console\Input\InputDefinition; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Zalas\Toolbox\Cli\Runner\DryRunner; use Zalas\Toolbox\Cli\ServiceContainer\RunnerFactory; @@ -17,10 +19,8 @@ class RunnerFactoryTest extends TestCase { - use ProphecyTrait; - /** - * @var ContainerInterface|ObjectProphecy + * @var ContainerInterface */ private $container; @@ -30,27 +30,38 @@ class RunnerFactoryTest extends TestCase private $runnerFactory; /** - * @var InputInterface|ObjectProphecy + * @var InputInterface */ private $input; /** - * @var OutputInterface|ObjectProphecy + * @var OutputInterface|MockObject */ private $output; protected function setUp(): void { - $this->container = $this->prophesize(ContainerInterface::class); - $this->input = $this->prophesize(InputInterface::class); - $this->output = $this->prophesize(OutputInterface::class); + $this->input = $this->givenInput([]); + $this->output = $this->createStub(OutputInterface::class); + + $this->container = new class([ InputInterface::class => &$this->input, OutputInterface::class => &$this->output, ]) implements ContainerInterface { + + public function __construct(private array $services) + { + } + + public function get(string $id) + { + return $this->services[$id]; + } - $this->container->get(InputInterface::class)->willReturn($this->input); - $this->container->get(OutputInterface::class)->willReturn($this->output); - $this->input->getOption('dry-run')->willReturn(false); - $this->input->hasOption('target-dir')->willReturn(false); + public function has(string $id): bool + { + return isset($this->services[$id]); + } + }; - $this->runnerFactory = new RunnerFactory($this->container->reveal()); + $this->runnerFactory = new RunnerFactory($this->container); } public function test_it_creates_the_passthru_runner_by_default() @@ -62,7 +73,7 @@ public function test_it_creates_the_passthru_runner_by_default() public function test_it_creates_the_dry_runner_if_dry_run_option_is_passed() { - $this->input->getOption('dry-run')->willReturn(true); + $this->givenInput(['--dry-run' => true]); $runner = $this->runnerFactory->createRunner(); @@ -71,8 +82,7 @@ public function test_it_creates_the_dry_runner_if_dry_run_option_is_passed() public function test_it_creates_the_parametrised_runner_if_target_dir_option_is_present() { - $this->input->hasOption('target-dir')->willReturn(true); - $this->input->getOption('target-dir')->willReturn('/usr/local/bin'); + $this->givenInput(['--target-dir' => '/usr/local/bin']); $runner = $this->runnerFactory->createRunner(); @@ -81,9 +91,9 @@ public function test_it_creates_the_parametrised_runner_if_target_dir_option_is_ public function test_the_parametrised_runner_includes_the_target_dir_parameter() { - $this->input->hasOption('target-dir')->willReturn(true); - $this->input->getOption('target-dir')->willReturn('/usr/local/bin'); - $this->input->getOption('dry-run')->willReturn(true); + $this->givenInput(['--target-dir' => '/usr/local/bin', '--dry-run' => true]); + + $this->output->expects(self::once())->method('writeln')->with('ls /usr/local/bin'); $runner = $this->runnerFactory->createRunner(); @@ -93,25 +103,22 @@ public function __toString(): string return 'ls %target-dir%'; } }); - - $this->output->writeln('ls /usr/local/bin')->shouldHaveBeenCalled(); } public function test_it_throws_an_exception_if_target_dir_does_not_exist() { $this->expectException(ContainerExceptionInterface::class); - $this->input->hasOption('target-dir')->willReturn(true); - $this->input->getOption('target-dir')->willReturn('/foo/bar/baz'); + $this->givenInput(['--target-dir' => '/foo/bar/baz']); $this->runnerFactory->createRunner(); } public function test_it_uses_the_real_path_as_target_dir() { - $this->input->hasOption('target-dir')->willReturn(true); - $this->input->getOption('target-dir')->willReturn(__DIR__.'/../../../bin'); - $this->input->getOption('dry-run')->willReturn(true); + $this->givenInput(['--target-dir' => __DIR__.'/../../../bin', '--dry-run' => true]); + + $this->output->expects(self::once())->method('writeln')->with(\sprintf('ls %s', \realpath(__DIR__.'/../../../bin'))); $runner = $this->runnerFactory->createRunner(); $runner->run(new class implements Command { @@ -120,7 +127,15 @@ public function __toString(): string return 'ls %target-dir%'; } }); + } + + private function givenInput(array $parameters): InputInterface + { + $this->input = new ArrayInput($parameters, new InputDefinition(\array_filter([ + new InputOption('dry-run', null, InputOption::VALUE_NONE), + isset($parameters['--target-dir']) ? new InputOption('target-dir', null, InputOption::VALUE_REQUIRED) : null, + ]))); - $this->output->writeln(\sprintf('ls %s', \realpath(__DIR__.'/../../../bin')))->shouldHaveBeenCalled(); + return $this->input; } } diff --git a/tests/Cli/ServiceContainerTest.php b/tests/Cli/ServiceContainerTest.php index ff1f8030..5cf05849 100644 --- a/tests/Cli/ServiceContainerTest.php +++ b/tests/Cli/ServiceContainerTest.php @@ -3,7 +3,6 @@ namespace Zalas\Toolbox\Tests\Cli; use PHPUnit\Framework\TestCase; -use Prophecy\PhpUnit\ProphecyTrait; use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; use Psr\Container\NotFoundExceptionInterface; @@ -18,8 +17,6 @@ class ServiceContainerTest extends TestCase { - use ProphecyTrait; - /** * @var ServiceContainer */ @@ -28,8 +25,8 @@ class ServiceContainerTest extends TestCase protected function setUp(): void { $this->container = new ServiceContainer(); - $this->container->set(InputInterface::class, $this->prophesize(InputInterface::class)->reveal()); - $this->container->set(OutputInterface::class, $this->prophesize(OutputInterface::class)->reveal()); + $this->container->set(InputInterface::class, $this->createStub(InputInterface::class)); + $this->container->set(OutputInterface::class, $this->createStub(OutputInterface::class)); } public function test_it_is_a_psr_container() @@ -69,7 +66,7 @@ public function test_it_throws_an_exception_if_unregistered_service_is_accessed( public function test_it_registers_a_runtime_service() { - $service = $this->prophesize(InputInterface::class)->reveal(); + $service = $this->createStub(InputInterface::class); $this->container->set(InputInterface::class, $service); diff --git a/tests/Runner/ParametrisedRunnerTest.php b/tests/Runner/ParametrisedRunnerTest.php index 7d25f36f..c3934540 100644 --- a/tests/Runner/ParametrisedRunnerTest.php +++ b/tests/Runner/ParametrisedRunnerTest.php @@ -2,32 +2,29 @@ namespace Zalas\Toolbox\Tests\Runner; +use PHPUnit\Framework\MockObject\Stub; use PHPUnit\Framework\TestCase; -use Prophecy\Argument; -use Prophecy\PhpUnit\ProphecyTrait; -use Prophecy\Prophecy\ObjectProphecy; use Zalas\Toolbox\Runner\ParametrisedRunner; use Zalas\Toolbox\Runner\Runner; use Zalas\Toolbox\Tool\Command; +use Zalas\Toolbox\Tool\Command\ShCommand; class ParametrisedRunnerTest extends TestCase { - use ProphecyTrait; - /** * @var ParametrisedRunner */ private $runner; /** - * @var Runner|ObjectProphecy + * @var Runner|Stub */ private $decoratedRunner; protected function setUp(): void { - $this->decoratedRunner = $this->prophesize(Runner::class); - $this->runner = new ParametrisedRunner($this->decoratedRunner->reveal(), ['%foo%' => 'ABC']); + $this->decoratedRunner = $this->createStub(Runner::class); + $this->runner = new ParametrisedRunner($this->decoratedRunner, ['%foo%' => 'ABC']); } public function test_it_is_a_runner() @@ -39,13 +36,15 @@ public function test_it_replaces_parameter_holders_in_the_command_before_running { $command = $this->command('echo "%foo%"'); - $this->decoratedRunner->run(Argument::that(function (Command $c) { - if ('echo "ABC"' !== $c->__toString()) { - throw new \RuntimeException(\sprintf('Expected `echo "ABC"`, but got `%s`.', $c->__toString())); - } + $this->decoratedRunner->method('run') + ->with(self::callback(function (Command $c) { + if ('echo "ABC"' !== $c->__toString()) { + throw new \RuntimeException(\sprintf('Expected `echo "ABC"`, but got `%s`.', $c->__toString())); + } - return true; - }))->willReturn(42); + return true; + })) + ->willReturn(42); $exitCode = $this->runner->run($command); @@ -54,9 +53,6 @@ public function test_it_replaces_parameter_holders_in_the_command_before_running private function command(string $commandString): Command { - $command = $this->prophesize(Command::class); - $command->__toString()->willReturn($commandString); - - return $command->reveal(); + return new ShCommand($commandString); } } diff --git a/tests/Tool/Command/MultiStepCommandTest.php b/tests/Tool/Command/MultiStepCommandTest.php index 14e06a11..ff9ef985 100644 --- a/tests/Tool/Command/MultiStepCommandTest.php +++ b/tests/Tool/Command/MultiStepCommandTest.php @@ -4,15 +4,13 @@ use InvalidArgumentException; use PHPUnit\Framework\TestCase; -use Prophecy\PhpUnit\ProphecyTrait; use Zalas\Toolbox\Tool\Collection; use Zalas\Toolbox\Tool\Command; use Zalas\Toolbox\Tool\Command\MultiStepCommand; +use Zalas\Toolbox\Tool\Command\ShCommand; class MultiStepCommandTest extends TestCase { - use ProphecyTrait; - public function test_it_is_a_command() { $command = new MultiStepCommand(Collection::create([$this->command('echo "A"')])); @@ -49,9 +47,6 @@ public function test_it_throws_an_exception_if_there_is_no_steps() private function command(string $commandString): Command { - $command = $this->prophesize(Command::class); - $command->__toString()->willReturn($commandString); - - return $command->reveal(); + return new ShCommand($commandString); } } diff --git a/tests/Tool/FilterTest.php b/tests/Tool/FilterTest.php index 5688884c..7444e212 100644 --- a/tests/Tool/FilterTest.php +++ b/tests/Tool/FilterTest.php @@ -3,14 +3,13 @@ namespace Zalas\Toolbox\Tests\Tool; use PHPUnit\Framework\TestCase; -use Prophecy\PhpUnit\ProphecyTrait; +use Zalas\Toolbox\Tool\Command\ShCommand; +use Zalas\Toolbox\Tool\Command\TestCommand; use Zalas\Toolbox\Tool\Filter; use Zalas\Toolbox\Tool\Tool; class FilterTest extends TestCase { - use ProphecyTrait; - public function test_it_returns_true_if_no_excluded_tags_were_defined() { $filter = new Filter([], []); @@ -97,9 +96,13 @@ public function test_it_returns_false_if_a_tag_is_both_included_and_excluded() private function tool(array $tags): Tool { - $tool = $this->prophesize(Tool::class); - $tool->tags()->willReturn($tags); - - return $tool->reveal(); + return new Tool( + 'any name', + 'any summary', + 'https://example.com', + $tags, + new ShCommand('any command'), + new TestCommand('any test command', 'any') + ); } } diff --git a/tests/Tool/ToolTest.php b/tests/Tool/ToolTest.php index 2dd24433..e7b1449f 100644 --- a/tests/Tool/ToolTest.php +++ b/tests/Tool/ToolTest.php @@ -4,19 +4,16 @@ namespace Zalas\Toolbox\Tests\Tool; use PHPUnit\Framework\TestCase; -use Prophecy\PhpUnit\ProphecyTrait; use TypeError; -use Zalas\Toolbox\Tool\Command; +use Zalas\Toolbox\Tool\Command\ShCommand; use Zalas\Toolbox\Tool\Tool; class ToolTest extends TestCase { - use ProphecyTrait; - public function test_it_exposes_its_properties() { - $command = $this->prophesize(Command::class)->reveal(); - $testCommand = $this->prophesize(Command::class)->reveal(); + $command = $this->anyCommand(); + $testCommand = $this->anyCommand(); $tool = new Tool('phpstan', 'Static analysis tool', 'https://github.com/phpstan/phpstan', ['qa', 'static-analysis'], $command, $testCommand); @@ -31,9 +28,17 @@ public function test_it_exposes_its_properties() public function test_tags_can_only_be_strings() { $this->expectException(TypeError::class); - $command = $this->prophesize(Command::class)->reveal(); - $testCommand = $this->prophesize(Command::class)->reveal(); + $command = $this->anyCommand(); + $testCommand = $this->anyCommand(); new Tool('phpstan', 'Static analysis tool', 'https://github.com/phpstan/phpstan', [['qa'], ['static-analysis']], $command, $testCommand); } + + /** + * @return object + */ + public function anyCommand(): object + { + return new ShCommand('any command'); + } } diff --git a/tests/UseCase/InstallToolsTest.php b/tests/UseCase/InstallToolsTest.php index 3909e191..2cad1d2a 100644 --- a/tests/UseCase/InstallToolsTest.php +++ b/tests/UseCase/InstallToolsTest.php @@ -2,10 +2,8 @@ namespace Zalas\Toolbox\Tests\UseCase; +use PHPUnit\Framework\MockObject\Stub; use PHPUnit\Framework\TestCase; -use Prophecy\Argument; -use Prophecy\PhpUnit\ProphecyTrait; -use Prophecy\Prophecy\ObjectProphecy; use Zalas\Toolbox\Tool\Collection; use Zalas\Toolbox\Tool\Command; use Zalas\Toolbox\Tool\Command\BoxBuildCommand; @@ -17,6 +15,7 @@ use Zalas\Toolbox\Tool\Command\PharDownloadCommand; use Zalas\Toolbox\Tool\Command\PhiveInstallCommand; use Zalas\Toolbox\Tool\Command\ShCommand; +use Zalas\Toolbox\Tool\Command\TestCommand; use Zalas\Toolbox\Tool\Filter; use Zalas\Toolbox\Tool\Tool; use Zalas\Toolbox\Tool\Tools; @@ -24,29 +23,27 @@ class InstallToolsTest extends TestCase { - use ProphecyTrait; - /** * @var InstallTools */ private $useCase; /** - * @var Tools|ObjectProphecy + * @var Tools|Stub */ private $tools; protected function setUp(): void { - $this->tools = $this->prophesize(Tools::class); - $this->useCase = new InstallTools($this->tools->reveal()); + $this->tools = $this->createStub(Tools::class); + $this->useCase = new InstallTools($this->tools); } public function test_it_returns_a_multi_step_command() { $filter = $this->filter(); - $this->tools->all($filter)->willReturn(Collection::create([$this->tool(new ShCommand('echo "Foo"'))])); + $this->givenToolsFor($filter, Collection::create([$this->tool(new ShCommand('echo "Foo"'))])); $command = $this->useCase->__invoke($filter); @@ -55,7 +52,7 @@ public function test_it_returns_a_multi_step_command() public function test_it_groups_composer_global_install_commands() { - $this->tools->all(Argument::type(Filter::class))->willReturn(Collection::create([ + $this->givenTools(Collection::create([ $this->tool(new ComposerGlobalInstallCommand('phpstan/phpstan')), $this->tool(new ComposerGlobalInstallCommand('phan/phan')), ])); @@ -67,7 +64,7 @@ public function test_it_groups_composer_global_install_commands() public function test_it_does_not_include_empty_commands() { - $this->tools->all(Argument::type(Filter::class))->willReturn(Collection::create([ + $this->givenTools(Collection::create([ $this->tool(new ShCommand('echo "Foo"')), ])); @@ -79,7 +76,7 @@ public function test_it_does_not_include_empty_commands() public function test_it_groups_composer_bin_plugin_commands() { - $this->tools->all(Argument::type(Filter::class))->willReturn(Collection::create([ + $this->givenTools(Collection::create([ $this->tool(new ComposerBinPluginCommand('phpstan/phpstan', 'tools', Collection::create([]))), $this->tool(new ComposerBinPluginCommand('phan/phan', 'tools', Collection::create([]))), ])); @@ -91,7 +88,7 @@ public function test_it_groups_composer_bin_plugin_commands() public function test_it_includes_installation_tagged_commands_before_other_ones() { - $this->tools->all(Argument::type(Filter::class))->willReturn(Collection::create([ + $this->givenTools(Collection::create([ $this->tool(new ShCommand('echo "Foo"')), $this->tool(new ShCommand('echo "Installation"'), [InstallTools::PRE_INSTALLATION_TAG]), ])); @@ -104,7 +101,7 @@ public function test_it_includes_installation_tagged_commands_before_other_ones( public function test_it_includes_shell_commands() { - $this->tools->all(Argument::type(Filter::class))->willReturn(Collection::create([ + $this->givenTools(Collection::create([ $this->tool(new ShCommand('echo "Foo"')), ])); @@ -115,7 +112,7 @@ public function test_it_includes_shell_commands() public function test_it_includes_multi_step_commands() { - $this->tools->all(Argument::type(Filter::class))->willReturn(Collection::create([ + $this->givenTools(Collection::create([ $this->tool(new MultiStepCommand(Collection::create([ new ShCommand('echo "Foo"'), new ShCommand('echo "Bar"') @@ -129,7 +126,7 @@ public function test_it_includes_multi_step_commands() public function test_it_includes_composer_install_commands() { - $this->tools->all(Argument::type(Filter::class))->willReturn(Collection::create([ + $this->givenTools(Collection::create([ $this->tool(new ComposerInstallCommand('git@github.com:phpspec/phpspec.git', '/usr/local/bin')), ])); @@ -140,7 +137,7 @@ public function test_it_includes_composer_install_commands() public function test_it_includes_box_build_commands() { - $this->tools->all(Argument::type(Filter::class))->willReturn(Collection::create([ + $this->givenTools(Collection::create([ $this->tool(new BoxBuildCommand('https://github.com/behat/behat.git', 'behat.phar', '/tools/behat', '/tmp')), ])); @@ -151,7 +148,7 @@ public function test_it_includes_box_build_commands() public function test_it_includes_phar_download_commands() { - $this->tools->all(Argument::type(Filter::class))->willReturn(Collection::create([ + $this->givenTools(Collection::create([ $this->tool(new PharDownloadCommand('https://github.com/sensiolabs-de/deptrac/releases/download/0.2.0/deptrac-0.2.0.phar', '/tools/phar')), ])); @@ -162,7 +159,7 @@ public function test_it_includes_phar_download_commands() public function test_it_includes_phive_install_commands() { - $this->tools->all(Argument::type(Filter::class))->willReturn(Collection::create([ + $this->givenTools(Collection::create([ $this->tool(new PhiveInstallCommand('phpunit', '/tools/phpunit')), ])); @@ -172,7 +169,7 @@ public function test_it_includes_phive_install_commands() public function test_it_includes_file_download_commands() { - $this->tools->all(Argument::type(Filter::class))->willReturn(Collection::create([ + $this->givenTools(Collection::create([ $this->tool(new FileDownloadCommand('https://github.com/fabpot/local-php-security-checker/releases/download/v1.0.0/local-php-security-checker_1.0.0_linux_amd64', '/tools/security-checker')), ])); @@ -188,10 +185,26 @@ private function filter(): Filter private function tool(Command $command, array $tags = []): Tool { - $tool = $this->prophesize(Tool::class); - $tool->command()->willReturn($command); - $tool->tags()->willReturn($tags); + return new Tool( + "any name", + "any summary", + "https://example.com", + $tags, + $command, + new TestCommand("any test command", "any test name") + ); + } + + private function givenToolsFor(Filter $filter, Collection $tools): void + { + $this->tools->method('all') + ->with($filter) + ->willReturn($tools); + } - return $tool->reveal(); + private function givenTools(Collection $tools): void + { + $this->tools->method('all') + ->willReturn($tools); } } diff --git a/tests/UseCase/ListToolsTest.php b/tests/UseCase/ListToolsTest.php index e47bf469..fe1b1adb 100644 --- a/tests/UseCase/ListToolsTest.php +++ b/tests/UseCase/ListToolsTest.php @@ -3,8 +3,9 @@ namespace Zalas\Toolbox\Tests\UseCase; use PHPUnit\Framework\TestCase; -use Prophecy\PhpUnit\ProphecyTrait; use Zalas\Toolbox\Tool\Collection; +use Zalas\Toolbox\Tool\Command; +use Zalas\Toolbox\Tool\Command\TestCommand; use Zalas\Toolbox\Tool\Filter; use Zalas\Toolbox\Tool\Tool; use Zalas\Toolbox\Tool\Tools; @@ -12,20 +13,14 @@ class ListToolsTest extends TestCase { - use ProphecyTrait; - public function test_it_returns_loaded_tools() { - $tools = Collection::create([ - $this->prophesize(Tool::class)->reveal(), - $this->prophesize(Tool::class)->reveal(), - ]); + $tools = Collection::create([$this->anyTool(), $this->anyTool()]); $filter = $this->filter(); - $repository = $this->prophesize(Tools::class); - $repository->all($filter)->willReturn($tools); + $repository = $this->givenToolsFor($filter, $tools); - $useCase = new ListTools($repository->reveal()); + $useCase = new ListTools($repository); $this->assertSame($tools, $useCase($filter)); } @@ -34,4 +29,24 @@ private function filter(): Filter { return new Filter([], []); } + + private function anyTool(): Tool + { + return new Tool( + "any name", + "any summary", + "https://example.com", + [], + new Command\ShCommand("any command"), + new TestCommand("any test command", "any test name") + ); + } + + private function givenToolsFor(Filter $filter, Collection $tools): Tools + { + $repository = $this->createStub(Tools::class); + $repository->method('all')->with($filter)->willReturn($tools); + + return $repository; + } } diff --git a/tests/UseCase/TestToolsTest.php b/tests/UseCase/TestToolsTest.php index 74ba8f89..f0afd517 100644 --- a/tests/UseCase/TestToolsTest.php +++ b/tests/UseCase/TestToolsTest.php @@ -3,9 +3,9 @@ namespace Zalas\Toolbox\Tests\UseCase; use PHPUnit\Framework\TestCase; -use Prophecy\PhpUnit\ProphecyTrait; use Zalas\Toolbox\Tool\Collection; use Zalas\Toolbox\Tool\Command; +use Zalas\Toolbox\Tool\Command\ShCommand; use Zalas\Toolbox\Tool\Filter; use Zalas\Toolbox\Tool\Tool; use Zalas\Toolbox\Tool\Tools; @@ -13,8 +13,6 @@ class TestToolsTest extends TestCase { - use ProphecyTrait; - public function test_it_returns_test_aggregated_test_command() { $testCommands = [ @@ -31,30 +29,29 @@ public function test_it_returns_test_aggregated_test_command() private function tool(Command $testCommand): Tool { - $tool = $this->prophesize(Tool::class); - $tool->testCommand()->willReturn($testCommand); - $tool->tags()->willReturn([]); - - return $tool->reveal(); + return new Tool( + "any name", + "any summary", + "https://example.com", + [], + new Command\ShCommand("any command"), + $testCommand + ); } private function command(string $command): Command { - $c = $this->prophesize(Command::class); - $c->__toString()->willReturn($command); - - return $c->reveal(); + return new ShCommand($command); } private function tools(array $testCommands, Filter $filter): Tools { - $tools = $this->prophesize(Tools::class); - $tools->all($filter)->willReturn(Collection::create([ - $this->tool($testCommands[0]), - $this->tool($testCommands[1]), - ])); + $tools = $this->createStub(Tools::class); + $tools->method('all')->with($filter)->willReturn(Collection::create( + \array_map(fn ($command) => $this->tool($command), $testCommands) + )); - return $tools->reveal(); + return $tools; } private function filter(): Filter