From 70a9d0c838a02d0a40f7a9fc2c11692f7a5173b0 Mon Sep 17 00:00:00 2001 From: Jakub Zalas Date: Wed, 29 Aug 2018 21:37:03 +0100 Subject: [PATCH] Extract the json package --- bin/devkit.php | 3 +- depfile.yml | 13 +- src/Cli/ServiceContainer.php | 3 +- src/{Tool/Command => Json/Factory}/Assert.php | 2 +- src/Json/Factory/BoxBuildCommandFactory.php | 16 ++ .../ComposerBinPluginCommandFactory.php | 16 ++ .../ComposerGlobalInstallCommandFactory.php | 16 ++ .../Factory/ComposerInstallCommandFactory.php | 16 ++ .../Factory/FileDownloadCommandFactory.php | 16 ++ .../Factory/PharDownloadCommandFactory.php | 16 ++ src/Json/Factory/ToolFactory.php | 56 +++++ src/Json/JsonTools.php | 82 +++++++ src/Tool/Command/BoxBuildCommand.php | 9 +- src/Tool/Command/ComposerBinPluginCommand.php | 7 - .../Command/ComposerGlobalInstallCommand.php | 7 - src/Tool/Command/ComposerInstallCommand.php | 7 - src/Tool/Command/FileDownloadCommand.php | 9 +- src/Tool/Command/PharDownloadCommand.php | 9 +- src/Tool/Tool.php | 54 ----- src/Tool/Tools.php | 70 +----- .../Command => Json/Factory}/AssertTest.php | 4 +- .../Factory/BoxBuildCommandFactoryTest.php | 67 ++++++ .../ComposerBinPluginCommandFactoryTest.php | 46 ++++ ...omposerGlobalInstallCommandFactoryTest.php | 28 +++ .../ComposerInstallCommandFactoryTest.php | 31 +++ .../FileDownloadCommandFactoryTest.php | 46 ++++ .../PharDownloadCommandFactoryTest.php | 46 ++++ tests/Json/Factory/ToolFactoryTest.php | 205 ++++++++++++++++++ .../ToolsTest.php => Json/JsonToolsTest.php} | 20 +- tests/Tool/Command/BoxBuildCommandTest.php | 94 +++----- .../Command/ComposerBinPluginCommandTest.php | 32 +-- .../ComposerGlobalInstallCommandTest.php | 21 +- .../ComposerGlobalMultiInstallCommandTest.php | 8 +- .../Command/ComposerInstallCommandTest.php | 44 +--- .../Tool/Command/FileDownloadCommandTest.php | 32 +-- .../Tool/Command/PharDownloadCommandTest.php | 32 +-- tests/Tool/ToolTest.php | 195 ----------------- tests/UseCase/InstallToolsTest.php | 14 +- 38 files changed, 809 insertions(+), 583 deletions(-) rename src/{Tool/Command => Json/Factory}/Assert.php (92%) create mode 100644 src/Json/Factory/BoxBuildCommandFactory.php create mode 100644 src/Json/Factory/ComposerBinPluginCommandFactory.php create mode 100644 src/Json/Factory/ComposerGlobalInstallCommandFactory.php create mode 100644 src/Json/Factory/ComposerInstallCommandFactory.php create mode 100644 src/Json/Factory/FileDownloadCommandFactory.php create mode 100644 src/Json/Factory/PharDownloadCommandFactory.php create mode 100644 src/Json/Factory/ToolFactory.php create mode 100644 src/Json/JsonTools.php rename tests/{Tool/Command => Json/Factory}/AssertTest.php (84%) create mode 100644 tests/Json/Factory/BoxBuildCommandFactoryTest.php create mode 100644 tests/Json/Factory/ComposerBinPluginCommandFactoryTest.php create mode 100644 tests/Json/Factory/ComposerGlobalInstallCommandFactoryTest.php create mode 100644 tests/Json/Factory/ComposerInstallCommandFactoryTest.php create mode 100644 tests/Json/Factory/FileDownloadCommandFactoryTest.php create mode 100644 tests/Json/Factory/PharDownloadCommandFactoryTest.php create mode 100644 tests/Json/Factory/ToolFactoryTest.php rename tests/{Tool/ToolsTest.php => Json/JsonToolsTest.php} (74%) diff --git a/bin/devkit.php b/bin/devkit.php index fade4136..4eb1314a 100755 --- a/bin/devkit.php +++ b/bin/devkit.php @@ -9,6 +9,7 @@ use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Zalas\Toolbox\Cli\Runner; +use Zalas\Toolbox\Json\JsonTools; use Zalas\Toolbox\Tool\Command; use Zalas\Toolbox\Tool\Command\ShCommand; use Zalas\Toolbox\Tool\Tool; @@ -30,7 +31,7 @@ protected function execute(InputInterface $input, OutputInterface $output) { $jsonPath = $input->getOption('tools'); $readmePath = $input->getOption('readme'); - $tools = (new Tools($jsonPath))->all(); + $tools = (new JsonTools($jsonPath))->all(); $toolsList = $tools->reduce('', function ($acc, Tool $tool) { return $acc . sprintf('* %s - [%s](%s)', $tool->name(), $tool->summary(), $tool->website()) . PHP_EOL; }); diff --git a/depfile.yml b/depfile.yml index bc32f702..a0cca350 100644 --- a/depfile.yml +++ b/depfile.yml @@ -6,6 +6,10 @@ layers: collectors: - type: className regex: ^Zalas\\Toolbox\\Cli\\.* + - name: Json + collectors: + - type: className + regex: ^Zalas\\Toolbox\\Json\\.* - name: Tool collectors: - type: className @@ -32,11 +36,7 @@ layers: must_not: # must not be one of the known vendors - type: className - regex: ^Zalas\\Toolbox\\Cli\\.* - - type: className - regex: ^Zalas\\Toolbox\\Tool\\.* - - type: className - regex: ^Zalas\\Toolbox\\UseCase\\.* + regex: ^Zalas\\Toolbox\\(Cli|Json|Tool|UseCase)\\.* - type: className regex: ^Psr\\Container\\.* - type: className @@ -44,9 +44,12 @@ layers: ruleset: Cli: - Tool + - Json - UseCase - Symfony Console - Psr Container + Json: + - Tool Tool: UseCase: - Tool diff --git a/src/Cli/ServiceContainer.php b/src/Cli/ServiceContainer.php index bd8b2693..294404a3 100644 --- a/src/Cli/ServiceContainer.php +++ b/src/Cli/ServiceContainer.php @@ -9,6 +9,7 @@ use Zalas\Toolbox\Cli\Command\InstallCommand; use Zalas\Toolbox\Cli\Command\ListCommand; use Zalas\Toolbox\Cli\Command\TestCommand; +use Zalas\Toolbox\Json\JsonTools; use Zalas\Toolbox\Tool\Tools; use Zalas\Toolbox\UseCase\InstallTools; use Zalas\Toolbox\UseCase\ListTools; @@ -102,6 +103,6 @@ private function createTestToolsUseCase(): TestTools private function createTools(): Tools { - return new Tools($this->getParameter('toolbox_json')); + return new JsonTools($this->getParameter('toolbox_json')); } } diff --git a/src/Tool/Command/Assert.php b/src/Json/Factory/Assert.php similarity index 92% rename from src/Tool/Command/Assert.php rename to src/Json/Factory/Assert.php index b1a4f5d9..1ff0a1e6 100644 --- a/src/Tool/Command/Assert.php +++ b/src/Json/Factory/Assert.php @@ -1,6 +1,6 @@ $command) { + $commands = $commands->merge(self::createCommands($type, $command)); + } + + if (0 === $commands->count()) { + throw new \RuntimeException(\sprintf('No valid command defined for the tool: %s', \json_encode($tool))); + } + + return 1 === $commands->count() ? $commands->toArray()[0] : new MultiStepCommand($commands); + } + + private static function createCommands($type, $command): Collection + { + $factories = [ + 'phar-download' => \sprintf('%s::import', PharDownloadCommandFactory::class), + 'file-download' => \sprintf('%s::import', FileDownloadCommandFactory::class), + 'box-build' => \sprintf('%s::import', BoxBuildCommandFactory::class), + 'composer-install' => \sprintf('%s::import', ComposerInstallCommandFactory::class), + 'composer-global-install' => \sprintf('%s::import', ComposerGlobalInstallCommandFactory::class), + 'composer-bin-plugin' => \sprintf('%s::import', ComposerBinPluginCommandFactory::class), + ]; + + if (!isset($factories[$type])) { + throw new \RuntimeException(\sprintf('Unrecognised command: "%s". Supported commands are: "%s".', $type, \implode(', ', \array_keys($factories)))); + } + + $command = !\is_numeric(\key($command)) ? [$command] : $command; + + return Collection::create(\array_map(function ($c) use ($type, $factories) { + return $factories[$type]($c); + }, $command)); + } +} diff --git a/src/Json/JsonTools.php b/src/Json/JsonTools.php new file mode 100644 index 00000000..a111b38a --- /dev/null +++ b/src/Json/JsonTools.php @@ -0,0 +1,82 @@ +resource = $resource; + } + + /** + * @return Collection|Tool[] + */ + public function all(): Collection + { + return $this->defaultTools() + ->merge(Collection::create( + \array_map(\sprintf('%s::import', ToolFactory::class), $this->loadJson()) + )); + } + + private function loadJson(): array + { + $json = \json_decode(\file_get_contents($this->resource), true); + + if (!$json) { + throw new RuntimeException(\sprintf('Failed to parse json: "%s"', $this->resource)); + } + + if (!isset($json['tools']) || !\is_array($json['tools'])) { + throw new RuntimeException(\sprintf('Failed to find any tools in: "%s".', $this->resource)); + } + + return $json['tools']; + } + + private function defaultTools(): Collection + { + return Collection::create([ + new Tool( + 'composer', + 'Dependency Manager for PHP', + 'https://getcomposer.org/', + new ShCommand('composer self-update'), + new TestCommand('composer list', 'composer') + ), + new Tool( + 'composer-bin-plugin', + 'Composer plugin to install bin vendors in isolated locations', + 'https://github.com/bamarni/composer-bin-plugin', + new ShCommand('composer global require bamarni/composer-bin-plugin'), + new TestCommand('composer global show bamarni/composer-bin-plugin', 'composer-bin-plugin') + ), + new Tool( + 'box', + 'An application for building and managing Phars', + 'https://box-project.github.io/box2/', + new ShCommand('curl -Ls https://box-project.github.io/box2/installer.php | php && mv box.phar /usr/local/bin/box && chmod +x /usr/local/bin/box'), + new TestCommand('box list', 'box') + ), + ]); + } +} diff --git a/src/Tool/Command/BoxBuildCommand.php b/src/Tool/Command/BoxBuildCommand.php index 2ac98f9c..3d372f92 100644 --- a/src/Tool/Command/BoxBuildCommand.php +++ b/src/Tool/Command/BoxBuildCommand.php @@ -11,7 +11,7 @@ final class BoxBuildCommand implements Command private $bin; private $version; - private function __construct(string $repository, string $phar, string $bin, ?string $version = null) + public function __construct(string $repository, string $phar, string $bin, ?string $version = null) { $this->repository = $repository; $this->phar = $phar; @@ -33,13 +33,6 @@ public function __toString(): string ); } - public static function import(array $definition): Command - { - Assert::requireFields(['repository', 'phar', 'bin'], $definition, 'BoxBuildCommand'); - - return new self($definition['repository'], $definition['phar'], $definition['bin'], $definition['version'] ?? null); - } - private function targetDir(): string { $targetDir = \preg_replace('#^.*/(.*?)(.git)?$#', '$1', $this->repository); diff --git a/src/Tool/Command/ComposerBinPluginCommand.php b/src/Tool/Command/ComposerBinPluginCommand.php index 48205531..ca45def5 100644 --- a/src/Tool/Command/ComposerBinPluginCommand.php +++ b/src/Tool/Command/ComposerBinPluginCommand.php @@ -20,13 +20,6 @@ public function __toString(): string return \sprintf('composer global bin %s require --no-suggest --prefer-dist --update-no-dev -n %s', $this->namespace, $this->package); } - public static function import(array $command): Command - { - Assert::requireFields(['package', 'namespace'], $command, 'ComposerBinPluginCommand'); - - return new self($command['package'], $command['namespace']); - } - public function package(): string { return $this->package; diff --git a/src/Tool/Command/ComposerGlobalInstallCommand.php b/src/Tool/Command/ComposerGlobalInstallCommand.php index 75c17260..b34aa836 100644 --- a/src/Tool/Command/ComposerGlobalInstallCommand.php +++ b/src/Tool/Command/ComposerGlobalInstallCommand.php @@ -18,13 +18,6 @@ public function __toString(): string return \sprintf('composer global require --no-suggest --prefer-dist --update-no-dev -n %s', $this->package); } - public static function import(array $command): Command - { - Assert::requireFields(['package'], $command, 'ComposerGlobalInstallCommand'); - - return new self($command['package']); - } - public function package(): string { return $this->package; diff --git a/src/Tool/Command/ComposerInstallCommand.php b/src/Tool/Command/ComposerInstallCommand.php index 52b31784..f35d7188 100644 --- a/src/Tool/Command/ComposerInstallCommand.php +++ b/src/Tool/Command/ComposerInstallCommand.php @@ -25,13 +25,6 @@ public function __toString(): string ); } - public static function import(array $command): Command - { - Assert::requireFields(['repository'], $command, 'ComposerInstallCommand'); - - return new self($command['repository'], $command['version'] ?? null); - } - private function targetDir(): string { $targetDir = \preg_replace('#^.*/(.*?)(.git)?$#', '$1', $this->repository); diff --git a/src/Tool/Command/FileDownloadCommand.php b/src/Tool/Command/FileDownloadCommand.php index 23c19e68..9b910f43 100644 --- a/src/Tool/Command/FileDownloadCommand.php +++ b/src/Tool/Command/FileDownloadCommand.php @@ -9,7 +9,7 @@ final class FileDownloadCommand implements Command private $url; private $file; - private function __construct(string $url, string $file) + public function __construct(string $url, string $file) { $this->url = $url; $this->file = $file; @@ -19,11 +19,4 @@ public function __toString(): string { return \sprintf('curl -Ls -w %%{filename_effective}\'\n\' %s -o %s', $this->url, $this->file); } - - public static function import(array $command): Command - { - Assert::requireFields(['url', 'file'], $command, 'FileDownloadCommand'); - - return new self($command['url'], $command['file']); - } } diff --git a/src/Tool/Command/PharDownloadCommand.php b/src/Tool/Command/PharDownloadCommand.php index af0bf53e..80375416 100644 --- a/src/Tool/Command/PharDownloadCommand.php +++ b/src/Tool/Command/PharDownloadCommand.php @@ -9,7 +9,7 @@ final class PharDownloadCommand implements Command private $phar; private $bin; - private function __construct(string $phar, string $bin) + public function __construct(string $phar, string $bin) { $this->phar = $phar; $this->bin = $bin; @@ -19,11 +19,4 @@ public function __toString(): string { return \sprintf('curl -Ls -w %%{filename_effective}\'\n\' %s -o %s && chmod +x %s', $this->phar, $this->bin, $this->bin); } - - public static function import(array $command): Command - { - Assert::requireFields(['phar', 'bin'], $command, 'PharDownloadCommand'); - - return new self($command['phar'], $command['bin']); - } } diff --git a/src/Tool/Tool.php b/src/Tool/Tool.php index 329cd4b0..ffc67f43 100644 --- a/src/Tool/Tool.php +++ b/src/Tool/Tool.php @@ -2,16 +2,6 @@ namespace Zalas\Toolbox\Tool; -use Zalas\Toolbox\Tool\Command\Assert; -use Zalas\Toolbox\Tool\Command\BoxBuildCommand; -use Zalas\Toolbox\Tool\Command\ComposerBinPluginCommand; -use Zalas\Toolbox\Tool\Command\ComposerGlobalInstallCommand; -use Zalas\Toolbox\Tool\Command\ComposerInstallCommand; -use Zalas\Toolbox\Tool\Command\FileDownloadCommand; -use Zalas\Toolbox\Tool\Command\MultiStepCommand; -use Zalas\Toolbox\Tool\Command\PharDownloadCommand; -use Zalas\Toolbox\Tool\Command\TestCommand; - class Tool { private $name; @@ -29,13 +19,6 @@ public function __construct(string $name, string $summary, string $website, Comm $this->testCommand = $testCommand; } - public static function import(array $tool): self - { - Assert::requireFields(['name', 'summary', 'website', 'command', 'test'], $tool, 'tool'); - - return new self($tool['name'], $tool['summary'], $tool['website'], self::importCommand($tool), new TestCommand($tool['test'], $tool['name'])); - } - public function name(): string { return $this->name; @@ -60,41 +43,4 @@ public function testCommand(): Command { return $this->testCommand; } - - private static function importCommand(array $tool): Command - { - $commands = Collection::create([]); - - foreach ($tool['command'] as $type => $command) { - $commands = $commands->merge(self::createCommands($type, $command)); - } - - if (0 === $commands->count()) { - throw new \RuntimeException(\sprintf('No valid command defined for the tool: %s', \json_encode($tool))); - } - - return 1 === $commands->count() ? $commands->toArray()[0] : new MultiStepCommand($commands); - } - - private static function createCommands($type, $command): Collection - { - $factories = [ - 'phar-download' => \sprintf('%s::import', PharDownloadCommand::class), - 'file-download' => \sprintf('%s::import', FileDownloadCommand::class), - 'box-build' => \sprintf('%s::import', BoxBuildCommand::class), - 'composer-install' => \sprintf('%s::import', ComposerInstallCommand::class), - 'composer-global-install' => \sprintf('%s::import', ComposerGlobalInstallCommand::class), - 'composer-bin-plugin' => \sprintf('%s::import', ComposerBinPluginCommand::class), - ]; - - if (!isset($factories[$type])) { - throw new \RuntimeException(\sprintf('Unrecognised command: "%s". Supported commands are: "%s".', $type, \implode(', ', \array_keys($factories)))); - } - - $command = !\is_numeric(\key($command)) ? [$command] : $command; - - return Collection::create(\array_map(function ($c) use ($type, $factories) { - return $factories[$type]($c); - }, $command)); - } } diff --git a/src/Tool/Tools.php b/src/Tool/Tools.php index e263422f..496dfc1c 100644 --- a/src/Tool/Tools.php +++ b/src/Tool/Tools.php @@ -2,77 +2,13 @@ namespace Zalas\Toolbox\Tool; -use InvalidArgumentException; use RuntimeException; -use Zalas\Toolbox\Tool\Command\ShCommand; -use Zalas\Toolbox\Tool\Command\TestCommand; -class Tools +interface Tools { - /** - * @var string - */ - private $resource; - - public function __construct(string $resource) - { - if (!\is_readable($resource)) { - throw new InvalidArgumentException(\sprintf('Could not read the file: "%s".', $resource)); - } - - $this->resource = $resource; - } - /** * @return Collection|Tool[] + * @throws RuntimeException in case tools cannot be loaded */ - public function all(): Collection - { - return $this->defaultTools() - ->merge(Collection::create( - \array_map(\sprintf('%s::import', Tool::class), $this->loadJson()) - )); - } - - private function loadJson(): array - { - $json = \json_decode(\file_get_contents($this->resource), true); - - if (!$json) { - throw new RuntimeException(\sprintf('Failed to parse json: "%s"', $this->resource)); - } - - if (!isset($json['tools']) || !\is_array($json['tools'])) { - throw new RuntimeException(\sprintf('Failed to find any tools in: "%s".', $this->resource)); - } - - return $json['tools']; - } - - private function defaultTools(): Collection - { - return Collection::create([ - new Tool( - 'composer', - 'Dependency Manager for PHP', - 'https://getcomposer.org/', - new ShCommand('composer self-update'), - new TestCommand('composer list', 'composer') - ), - new Tool( - 'composer-bin-plugin', - 'Composer plugin to install bin vendors in isolated locations', - 'https://github.com/bamarni/composer-bin-plugin', - new ShCommand('composer global require bamarni/composer-bin-plugin'), - new TestCommand('composer global show bamarni/composer-bin-plugin', 'composer-bin-plugin') - ), - new Tool( - 'box', - 'An application for building and managing Phars', - 'https://box-project.github.io/box2/', - new ShCommand('curl -Ls https://box-project.github.io/box2/installer.php | php && mv box.phar /usr/local/bin/box && chmod +x /usr/local/bin/box'), - new TestCommand('box list', 'box') - ), - ]); - } + public function all(): Collection; } diff --git a/tests/Tool/Command/AssertTest.php b/tests/Json/Factory/AssertTest.php similarity index 84% rename from tests/Tool/Command/AssertTest.php rename to tests/Json/Factory/AssertTest.php index e8ae5519..340914a1 100644 --- a/tests/Tool/Command/AssertTest.php +++ b/tests/Json/Factory/AssertTest.php @@ -1,9 +1,9 @@ self::REPOSITORY, + 'phar' => self::PHAR, + 'bin' => self::BIN, + 'version' => self::VERSION, + ]); + + $this->assertInstanceOf(BoxBuildCommand::class, $command); + $this->assertRegExp('#git checkout '.self::VERSION.'#', (string) $command); + } + + public function test_the_version_is_not_required() + { + $command = BoxBuildCommandFactory::import([ + 'repository' => self::REPOSITORY, + 'phar' => self::PHAR, + 'bin' => self::BIN, + ]); + + $this->assertInstanceOf(BoxBuildCommand::class, $command); + } + + /** + * @dataProvider provideRequiredProperties + */ + public function test_it_complains_if_any_of_required_properties_is_missing(string $property) + { + $this->expectException(\InvalidArgumentException::class); + + $properties = [ + 'repository' => self::REPOSITORY, + 'phar' => self::PHAR, + 'bin' => self::BIN, + ]; + + unset($properties[$property]); + + BoxBuildCommandFactory::import($properties); + } + + public function provideRequiredProperties(): \Generator + { + yield ['repository']; + yield ['phar']; + yield ['bin']; + } +} diff --git a/tests/Json/Factory/ComposerBinPluginCommandFactoryTest.php b/tests/Json/Factory/ComposerBinPluginCommandFactoryTest.php new file mode 100644 index 00000000..221434fb --- /dev/null +++ b/tests/Json/Factory/ComposerBinPluginCommandFactoryTest.php @@ -0,0 +1,46 @@ + self::PACKAGE, + 'namespace' => self::NAMESPACE, + ]); + + $this->assertInstanceOf(ComposerBinPluginCommand::class, $command); + } + + /** + * @dataProvider provideRequiredProperties + */ + public function test_it_complains_if_any_of_required_properties_is_missing(string $property) + { + $this->expectException(\InvalidArgumentException::class); + + $properties = [ + 'package' => self::PACKAGE, + 'namespace' => self::NAMESPACE, + ]; + + unset($properties[$property]); + + ComposerBinPluginCommandFactory::import($properties); + } + + public function provideRequiredProperties(): \Generator + { + yield ['package']; + yield ['namespace']; + } +} diff --git a/tests/Json/Factory/ComposerGlobalInstallCommandFactoryTest.php b/tests/Json/Factory/ComposerGlobalInstallCommandFactoryTest.php new file mode 100644 index 00000000..41c6d862 --- /dev/null +++ b/tests/Json/Factory/ComposerGlobalInstallCommandFactoryTest.php @@ -0,0 +1,28 @@ + self::PACKAGE, + ]); + + $this->assertInstanceOf(ComposerGlobalInstallCommand::class, $command); + } + + public function test_it_complains_if_package_is_missing() + { + $this->expectException(\InvalidArgumentException::class); + + ComposerGlobalInstallCommandFactory::import([]); + } +} diff --git a/tests/Json/Factory/ComposerInstallCommandFactoryTest.php b/tests/Json/Factory/ComposerInstallCommandFactoryTest.php new file mode 100644 index 00000000..e15b82f5 --- /dev/null +++ b/tests/Json/Factory/ComposerInstallCommandFactoryTest.php @@ -0,0 +1,31 @@ + self::REPOSITORY, + 'version' => self::VERSION, + ]); + + $this->assertInstanceOf(ComposerInstallCommand::class, $command); + $this->assertRegExp('#git checkout '.self::VERSION.'#', (string) $command); + } + + public function test_it_complains_if_repository_property_is_missing() + { + $this->expectException(\InvalidArgumentException::class); + + ComposerInstallCommandFactory::import([]); + } +} diff --git a/tests/Json/Factory/FileDownloadCommandFactoryTest.php b/tests/Json/Factory/FileDownloadCommandFactoryTest.php new file mode 100644 index 00000000..6dd9ff28 --- /dev/null +++ b/tests/Json/Factory/FileDownloadCommandFactoryTest.php @@ -0,0 +1,46 @@ + self::URL, + 'file' => self::FILE, + ]); + + $this->assertInstanceOf(FileDownloadCommand::class, $command); + } + + /** + * @dataProvider provideRequiredProperties + */ + public function test_it_complains_if_any_of_required_properties_is_missing(string $property) + { + $this->expectException(\InvalidArgumentException::class); + + $properties = [ + 'url' => self::URL, + 'file' => self::FILE, + ]; + + unset($properties[$property]); + + FileDownloadCommandFactory::import($properties); + } + + public function provideRequiredProperties(): \Generator + { + yield ['url']; + yield ['file']; + } +} diff --git a/tests/Json/Factory/PharDownloadCommandFactoryTest.php b/tests/Json/Factory/PharDownloadCommandFactoryTest.php new file mode 100644 index 00000000..21ae9ae7 --- /dev/null +++ b/tests/Json/Factory/PharDownloadCommandFactoryTest.php @@ -0,0 +1,46 @@ + self::PHAR, + 'bin' => self::BIN, + ]); + + $this->assertInstanceOf(PharDownloadCommand::class, $command); + } + + /** + * @dataProvider provideRequiredProperties + */ + public function test_it_complains_if_any_of_required_properties_is_missing(string $property) + { + $this->expectException(\InvalidArgumentException::class); + + $properties = [ + 'phar' => self::PHAR, + 'bin' => self::BIN, + ]; + + unset($properties[$property]); + + PharDownloadCommandFactory::import($properties); + } + + public function provideRequiredProperties(): \Generator + { + yield ['phar']; + yield ['bin']; + } +} diff --git a/tests/Json/Factory/ToolFactoryTest.php b/tests/Json/Factory/ToolFactoryTest.php new file mode 100644 index 00000000..fb8fcb9c --- /dev/null +++ b/tests/Json/Factory/ToolFactoryTest.php @@ -0,0 +1,205 @@ + 'phpstan', + 'summary' => 'Static analysis tool', + 'website' => 'https://github.com/phpstan/phpstan', + 'command' => [ + 'composer-bin-plugin' => [ + 'package' => 'phpstan/phpstan', + 'namespace' => 'tools' + ] + ], + 'test' => '/usr/bin/true', + ]); + + $this->assertSame('phpstan', $tool->name()); + $this->assertSame('Static analysis tool', $tool->summary()); + $this->assertSame('https://github.com/phpstan/phpstan', $tool->website()); + $this->assertInstanceOf(Command::class, $tool->command()); + $this->assertInstanceOf(TestCommand::class, $tool->testCommand()); + } + + public function test_it_imports_the_composer_bin_plugin_command() + { + $tool = ToolFactory::import($this->definition([ + 'command' => [ + 'composer-bin-plugin' => [ + 'package' => 'phpstan/phpstan', + 'namespace' => 'tools' + ] + ] + ])); + + $this->assertInstanceOf(ComposerBinPluginCommand::class, $tool->command()); + } + + public function test_it_imports_the_phar_download_command() + { + $tool = ToolFactory::import($this->definition([ + 'command' => [ + 'phar-download' => [ + 'phar' => 'phpstan/phpstan', + 'bin' => 'tools' + ] + ] + ])); + + $this->assertInstanceOf(PharDownloadCommand::class, $tool->command()); + } + + public function test_it_imports_the_file_download_command() + { + $tool = ToolFactory::import($this->definition([ + 'command' => [ + 'file-download' => [ + 'url' => 'http://example.com/file', + 'file' => 'file' + ] + ] + ])); + + $this->assertInstanceOf(FileDownloadCommand::class, $tool->command()); + } + + public function test_it_imports_the_box_build_command() + { + $tool = ToolFactory::import($this->definition([ + 'command' => [ + 'box-build' => [ + 'repository' => 'https://github.com/behat/behat.git', + 'phar' => 'behat.phar', + 'bin' => '/usr/local/bin/behat', + 'version' => 'v3.4.0', + ] + ] + ])); + + $this->assertInstanceOf(BoxBuildCommand::class, $tool->command()); + } + + public function test_it_imports_the_composer_install_command() + { + $tool = ToolFactory::import($this->definition([ + 'command' => [ + 'composer-install' => [ + 'repository' => 'https://github.com/behat/behat.git', + 'version' => 'v3.4.0', + ] + ] + ])); + + $this->assertInstanceOf(ComposerInstallCommand::class, $tool->command()); + } + + public function test_it_imports_the_composer_global_install_command() + { + $tool = ToolFactory::import($this->definition([ + 'command' => [ + 'composer-global-install' => [ + 'package' => 'behat/behat', + 'version' => 'v3.4.0', + ] + ] + ])); + + $this->assertInstanceOf(ComposerGlobalInstallCommand::class, $tool->command()); + } + public function test_it_imports_multiple_commands() + { + $tool = ToolFactory::import($this->definition([ + 'command' => [ + 'phar-download' => [ + 'phar' => 'phpstan/phpstan', + 'bin' => 'tools' + ], + 'file-download' => [ + [ + 'url' => 'http://example.com/file1', + 'file' => 'file1' + ], + [ + 'url' => 'http://example.com/file2', + 'file' => 'file2' + ] + ] + ] + ])); + + $this->assertInstanceOf(MultiStepCommand::class, $tool->command()); + } + + public function test_it_complains_if_it_cannot_recognise_the_command() + { + $this->expectException(\RuntimeException::class); + + ToolFactory::import($this->definition(['command' => ['foo' => ['phar' => 'phpstan/phpstan']]])); + } + + public function test_it_complains_if_the_command_is_empty() + { + $this->expectException(\RuntimeException::class); + + ToolFactory::import($this->definition(['command' => []])); + } + + /** + * @dataProvider provideRequiredProperties + */ + public function test_it_complains_if_any_of_required_properties_is_missing(string $property) + { + $this->expectException(\InvalidArgumentException::class); + + $properties = $this->definition(); + + unset($properties[$property]); + + ToolFactory::import($properties); + } + + public function provideRequiredProperties(): \Generator + { + yield ['name']; + yield ['summary']; + yield ['website']; + yield ['command']; + yield ['test']; + } + + private function definition(array $overrides = []): array + { + return \array_merge( + [ + 'name' => 'phpstan', + 'summary' => 'Static analysis tool', + 'website' => 'https://github.com/phpstan/phpstan', + 'command' => [ + 'composer-bin-plugin' => [ + 'package' => 'phpstan/phpstan', + 'namespace' => 'tools' + ] + ], + 'test' => '/usr/bin/true', + ], + $overrides + ); + } +} diff --git a/tests/Tool/ToolsTest.php b/tests/Json/JsonToolsTest.php similarity index 74% rename from tests/Tool/ToolsTest.php rename to tests/Json/JsonToolsTest.php index d8ce818f..861b207e 100644 --- a/tests/Tool/ToolsTest.php +++ b/tests/Json/JsonToolsTest.php @@ -1,20 +1,26 @@ assertInstanceOf(Tools::class, new JsonTools(__DIR__.'/../resources/tools.json')); + } + public function test_it_throws_an_exception_if_resource_is_missing() { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessageRegExp('/Could not read the file/'); - new Tools('/foo/tools.json'); + new JsonTools('/foo/tools.json'); } public function test_it_throws_an_exception_if_resource_contains_invalid_json() @@ -22,7 +28,7 @@ public function test_it_throws_an_exception_if_resource_contains_invalid_json() $this->expectException(RuntimeException::class); $this->expectExceptionMessageRegExp('/Failed to parse json/'); - $tools = new Tools(__DIR__.'/../resources/invalid.json'); + $tools = new JsonTools(__DIR__.'/../resources/invalid.json'); $tools->all(); } @@ -31,7 +37,7 @@ public function test_it_throws_an_exception_if_tools_are_not_present_in_the_reso $this->expectException(RuntimeException::class); $this->expectExceptionMessageRegExp('/Failed to find any tools/'); - $tools = new Tools(__DIR__.'/../resources/no-tools.json'); + $tools = new JsonTools(__DIR__.'/../resources/no-tools.json'); $tools->all(); } @@ -40,14 +46,14 @@ public function test_it_throws_an_exception_if_tools_is_not_a_collection() $this->expectException(RuntimeException::class); $this->expectExceptionMessageRegExp('/Failed to find any tools/'); - $tools = new Tools(__DIR__.'/../resources/invalid-tools.json'); + $tools = new JsonTools(__DIR__.'/../resources/invalid-tools.json'); $tools->all(); } public function test_it_loads_tools_from_the_resource_with_default_ones_prepended() { $tools = \iterator_to_array( - (new Tools(__DIR__.'/../resources/tools.json'))->all() + (new JsonTools(__DIR__.'/../resources/tools.json'))->all() ); $this->assertCount(8, $tools); diff --git a/tests/Tool/Command/BoxBuildCommandTest.php b/tests/Tool/Command/BoxBuildCommandTest.php index 311213d9..44efbdf8 100644 --- a/tests/Tool/Command/BoxBuildCommandTest.php +++ b/tests/Tool/Command/BoxBuildCommandTest.php @@ -8,87 +8,61 @@ class BoxBuildCommandTest extends TestCase { - const REPOSITORY = 'https://github.com/behat/behat.git'; + private const REPOSITORY = 'https://github.com/behat/behat.git'; - const PHAR = 'behat.phar'; + private const PHAR = 'behat.phar'; - const BIN = '/usr/local/bin/behat'; + private const BIN = '/usr/local/bin/behat'; - const VERSION = 'v3.4.0'; - - /** - * @var BoxBuildCommand - */ - private $command; - - protected function setUp() - { - $this->command = BoxBuildCommand::import([ - 'repository' => self::REPOSITORY, - 'phar' => self::PHAR, - 'bin' => self::BIN, - 'version' => self::VERSION, - ]); - } + private const VERSION = 'v3.4.0'; public function test_it_is_a_command() { - $this->assertInstanceOf(Command::class, $this->command); + $command = new BoxBuildCommand( + self::REPOSITORY, + self::PHAR, + self::BIN, + self::VERSION + ); + + $this->assertInstanceOf(Command::class, $command); } public function test_it_generates_the_installation_command() { - $this->assertRegExp('#git clone '.self::REPOSITORY.'#', (string) $this->command); - $this->assertRegExp('#cd /tools/behat#', (string) $this->command); - $this->assertRegExp('#git checkout '.self::VERSION.'#', (string) $this->command); - $this->assertRegExp('#composer install --no-dev --no-suggest --prefer-dist -n#', (string) $this->command); - $this->assertRegExp('#box build#', (string) $this->command); + $command = new BoxBuildCommand( + self::REPOSITORY, + self::PHAR, + self::BIN, + self::VERSION + ); + + $this->assertRegExp('#git clone '.self::REPOSITORY.'#', (string) $command); + $this->assertRegExp('#cd /tools/behat#', (string) $command); + $this->assertRegExp('#git checkout '.self::VERSION.'#', (string) $command); + $this->assertRegExp('#composer install --no-dev --no-suggest --prefer-dist -n#', (string) $command); + $this->assertRegExp('#box build#', (string) $command); } public function test_it_tries_to_guess_version_number_if_not_given_one() { - $command = BoxBuildCommand::import([ - 'repository' => self::REPOSITORY, - 'phar' => self::PHAR, - 'bin' => self::BIN, - ]); + $command = new BoxBuildCommand( + self::REPOSITORY, + self::PHAR, + self::BIN + ); $this->assertRegExp('#git checkout \$\(git describe --tags .*?\)#', (string) $command); } public function test_it_uses_a_generic_directory_if_name_cannot_be_guessed_from_the_repository() { - $command = BoxBuildCommand::import([ - 'repository' => 'example.com:foo.git', - 'phar' => self::PHAR, - 'bin' => self::BIN, - ]); + $command = new BoxBuildCommand( + 'example.com:foo.git', + self::PHAR, + self::BIN + ); $this->assertRegExp('#cd /tools/tmp#', (string) $command); } - - /** - * @dataProvider provideRequiredProperties - */ - public function test_it_complains_if_any_of_required_properties_is_missing(string $property) - { - $this->expectException(\InvalidArgumentException::class); - - $properties = [ - 'repository' => self::REPOSITORY, - 'phar' => self::PHAR, - 'bin' => self::BIN, - ]; - - unset($properties[$property]); - - BoxBuildCommand::import($properties); - } - - public function provideRequiredProperties(): \Generator - { - yield ['repository']; - yield ['phar']; - yield ['bin']; - } } diff --git a/tests/Tool/Command/ComposerBinPluginCommandTest.php b/tests/Tool/Command/ComposerBinPluginCommandTest.php index becb3797..05d3fef1 100644 --- a/tests/Tool/Command/ComposerBinPluginCommandTest.php +++ b/tests/Tool/Command/ComposerBinPluginCommandTest.php @@ -8,8 +8,8 @@ class ComposerBinPluginCommandTest extends TestCase { - const PACKAGE = 'phpstan/phpstan'; - const NAMESPACE = 'tools'; + private const PACKAGE = 'phpstan/phpstan'; + private const NAMESPACE = 'tools'; /** * @var ComposerBinPluginCommand @@ -18,10 +18,7 @@ class ComposerBinPluginCommandTest extends TestCase protected function setUp() { - $this->command = ComposerBinPluginCommand::import([ - 'package' => self::PACKAGE, - 'namespace' => self::NAMESPACE, - ]); + $this->command = new ComposerBinPluginCommand(self::PACKAGE, self::NAMESPACE); } public function test_it_is_a_command() @@ -39,27 +36,4 @@ public function test_it_exposes_the_package_and_namespace() $this->assertSame(self::PACKAGE, $this->command->package()); $this->assertSame(self::NAMESPACE, $this->command->namespace()); } - - /** - * @dataProvider provideRequiredProperties - */ - public function test_it_complains_if_any_of_required_properties_is_missing(string $property) - { - $this->expectException(\InvalidArgumentException::class); - - $properties = [ - 'package' => self::PACKAGE, - 'namespace' => self::NAMESPACE, - ]; - - unset($properties[$property]); - - ComposerBinPluginCommand::import($properties); - } - - public function provideRequiredProperties(): \Generator - { - yield ['package']; - yield ['namespace']; - } } diff --git a/tests/Tool/Command/ComposerGlobalInstallCommandTest.php b/tests/Tool/Command/ComposerGlobalInstallCommandTest.php index f9a5a5c9..3b7f4c4c 100644 --- a/tests/Tool/Command/ComposerGlobalInstallCommandTest.php +++ b/tests/Tool/Command/ComposerGlobalInstallCommandTest.php @@ -8,7 +8,7 @@ class ComposerGlobalInstallCommandTest extends TestCase { - const PACKAGE = 'phan/phan'; + private const PACKAGE = 'phan/phan'; /** * @var ComposerGlobalInstallCommand @@ -17,9 +17,7 @@ class ComposerGlobalInstallCommandTest extends TestCase protected function setUp() { - $this->command = ComposerGlobalInstallCommand::import([ - 'package' => self::PACKAGE, - ]); + $this->command = new ComposerGlobalInstallCommand(self::PACKAGE); } public function test_it_is_a_command() @@ -27,20 +25,13 @@ public function test_it_is_a_command() $this->assertInstanceOf(Command::class, $this->command); } - public function test_it_generates_the_installation_command() - { - $this->assertRegExp('#composer global require .*? phan/phan#', (string) $this->command); - } - - public function test_it_complains_if_package_is_missing() + public function test_it_exposes_the_package_name() { - $this->expectException(\InvalidArgumentException::class); - - ComposerGlobalInstallCommand::import([]); + $this->assertSame(self::PACKAGE, $this->command->package()); } - public function test_it_exposes_the_package_name() + public function test_it_generates_the_installation_command() { - $this->assertSame(self::PACKAGE, $this->command->package()); + $this->assertRegExp('#composer global require .*? phan/phan#', (string) $this->command); } } diff --git a/tests/Tool/Command/ComposerGlobalMultiInstallCommandTest.php b/tests/Tool/Command/ComposerGlobalMultiInstallCommandTest.php index 3c1bd982..54a6e478 100644 --- a/tests/Tool/Command/ComposerGlobalMultiInstallCommandTest.php +++ b/tests/Tool/Command/ComposerGlobalMultiInstallCommandTest.php @@ -13,8 +13,8 @@ class ComposerGlobalMultiInstallCommandTest extends TestCase public function test_it_is_a_command() { $command = new ComposerGlobalMultiInstallCommand(Collection::create([ - ComposerGlobalInstallCommand::import(['package' => 'phan/phan']), - ComposerGlobalInstallCommand::import(['package' => 'phpstan/phpstan']), + new ComposerGlobalInstallCommand('phan/phan'), + new ComposerGlobalInstallCommand('phpstan/phpstan'), ])); $this->assertInstanceOf(Command::class, $command); @@ -23,8 +23,8 @@ public function test_it_is_a_command() public function test_it_generates_a_single_installation_command() { $command = new ComposerGlobalMultiInstallCommand(Collection::create([ - ComposerGlobalInstallCommand::import(['package' => 'phan/phan']), - ComposerGlobalInstallCommand::import(['package' => 'phpstan/phpstan']), + new ComposerGlobalInstallCommand('phan/phan'), + new ComposerGlobalInstallCommand('phpstan/phpstan'), ])); $this->assertRegExp('#composer global require .*? phan/phan phpstan/phpstan#', (string) $command); diff --git a/tests/Tool/Command/ComposerInstallCommandTest.php b/tests/Tool/Command/ComposerInstallCommandTest.php index a5e93293..4dec0ffc 100644 --- a/tests/Tool/Command/ComposerInstallCommandTest.php +++ b/tests/Tool/Command/ComposerInstallCommandTest.php @@ -8,56 +8,36 @@ class ComposerInstallCommandTest extends TestCase { - const REPOSITORY = 'https://github.com/behat/behat.git'; - const VERSION = 'v3.4.0'; - - /** - * @var ComposerInstallCommand - */ - private $command; - - protected function setUp() - { - $this->command = ComposerInstallCommand::import([ - 'repository' => self::REPOSITORY, - 'version' => self::VERSION, - ]); - } + private const REPOSITORY = 'https://github.com/behat/behat.git'; + private const VERSION = 'v3.4.0'; public function test_it_is_a_command() { - $this->assertInstanceOf(Command::class, $this->command); + $command = new ComposerInstallCommand(self::REPOSITORY, self::VERSION); + + $this->assertInstanceOf(Command::class, $command); } public function test_it_generates_the_installation_command() { - $this->assertRegExp('#git clone '.self::REPOSITORY.'#', (string) $this->command); - $this->assertRegExp('#git checkout '.self::VERSION.'#', (string) $this->command); - $this->assertRegExp('#composer install --no-dev --no-suggest --prefer-dist -n#', (string) $this->command); + $command = new ComposerInstallCommand(self::REPOSITORY, self::VERSION); + + $this->assertRegExp('#git clone '.self::REPOSITORY.'#', (string) $command); + $this->assertRegExp('#git checkout '.self::VERSION.'#', (string) $command); + $this->assertRegExp('#composer install --no-dev --no-suggest --prefer-dist -n#', (string) $command); } public function test_it_tries_to_guess_version_number_if_not_given_one() { - $command = ComposerInstallCommand::import([ - 'repository' => self::REPOSITORY, - ]); + $command = new ComposerInstallCommand(self::REPOSITORY); $this->assertRegExp('#git checkout \$\(git describe --tags .*?\)#', (string) $command); } public function test_it_uses_a_generic_directory_if_name_cannot_be_guessed_from_the_repository() { - $command = ComposerInstallCommand::import([ - 'repository' => 'example.com:foo.git', - ]); + $command = new ComposerInstallCommand('example.com:foo.git'); $this->assertRegExp('#cd /tools/tmp#', (string) $command); } - - public function test_it_complains_if_repository_property_is_missing() - { - $this->expectException(\InvalidArgumentException::class); - - ComposerInstallCommand::import([]); - } } diff --git a/tests/Tool/Command/FileDownloadCommandTest.php b/tests/Tool/Command/FileDownloadCommandTest.php index 84b74ce0..01969c59 100644 --- a/tests/Tool/Command/FileDownloadCommandTest.php +++ b/tests/Tool/Command/FileDownloadCommandTest.php @@ -8,8 +8,8 @@ class FileDownloadCommandTest extends TestCase { - const URL = 'https://example.com/file'; - const FILE = '/usr/local/bin/file.txt'; + private const URL = 'https://example.com/file'; + private const FILE = '/usr/local/bin/file.txt'; /** * @var FileDownloadCommand @@ -18,10 +18,7 @@ class FileDownloadCommandTest extends TestCase protected function setUp() { - $this->command = FileDownloadCommand::import([ - 'url' => self::URL, - 'file' => self::FILE, - ]); + $this->command = new FileDownloadCommand(self::URL, self::FILE); } public function test_it_is_a_command() @@ -33,27 +30,4 @@ public function test_it_generates_the_installation_command() { $this->assertRegExp(\sprintf('#curl .*? %s -o %s#', self::URL, self::FILE), (string) $this->command); } - - /** - * @dataProvider provideRequiredProperties - */ - public function test_it_complains_if_any_of_required_properties_is_missing(string $property) - { - $this->expectException(\InvalidArgumentException::class); - - $properties = [ - 'url' => self::URL, - 'file' => self::FILE, - ]; - - unset($properties[$property]); - - FileDownloadCommand::import($properties); - } - - public function provideRequiredProperties(): \Generator - { - yield ['url']; - yield ['file']; - } } diff --git a/tests/Tool/Command/PharDownloadCommandTest.php b/tests/Tool/Command/PharDownloadCommandTest.php index bb960923..07941f74 100644 --- a/tests/Tool/Command/PharDownloadCommandTest.php +++ b/tests/Tool/Command/PharDownloadCommandTest.php @@ -8,8 +8,8 @@ class PharDownloadCommandTest extends TestCase { - const PHAR = 'https://example.com/foo.phar'; - const BIN = '/usr/local/bin/foo'; + private const PHAR = 'https://example.com/foo.phar'; + private const BIN = '/usr/local/bin/foo'; /** * @var FileDownloadCommand @@ -18,10 +18,7 @@ class PharDownloadCommandTest extends TestCase protected function setUp() { - $this->command = PharDownloadCommand::import([ - 'phar' => self::PHAR, - 'bin' => self::BIN, - ]); + $this->command = new PharDownloadCommand(self::PHAR, self::BIN); } public function test_it_is_a_command() @@ -33,27 +30,4 @@ public function test_it_generates_the_installation_command() { $this->assertRegExp(\sprintf('#curl .*? %s -o %s#', self::PHAR, self::BIN), (string) $this->command); } - - /** - * @dataProvider provideRequiredProperties - */ - public function test_it_complains_if_any_of_required_properties_is_missing(string $property) - { - $this->expectException(\InvalidArgumentException::class); - - $properties = [ - 'phar' => self::PHAR, - 'bin' => self::BIN, - ]; - - unset($properties[$property]); - - PharDownloadCommand::import($properties); - } - - public function provideRequiredProperties(): \Generator - { - yield ['phar']; - yield ['bin']; - } } diff --git a/tests/Tool/ToolTest.php b/tests/Tool/ToolTest.php index 16248bd9..e33deed0 100644 --- a/tests/Tool/ToolTest.php +++ b/tests/Tool/ToolTest.php @@ -5,14 +5,6 @@ use PHPUnit\Framework\TestCase; use Zalas\Toolbox\Tool\Command; -use Zalas\Toolbox\Tool\Command\BoxBuildCommand; -use Zalas\Toolbox\Tool\Command\ComposerBinPluginCommand; -use Zalas\Toolbox\Tool\Command\ComposerGlobalInstallCommand; -use Zalas\Toolbox\Tool\Command\ComposerInstallCommand; -use Zalas\Toolbox\Tool\Command\FileDownloadCommand; -use Zalas\Toolbox\Tool\Command\MultiStepCommand; -use Zalas\Toolbox\Tool\Command\PharDownloadCommand; -use Zalas\Toolbox\Tool\Command\TestCommand; use Zalas\Toolbox\Tool\Tool; class ToolTest extends TestCase @@ -30,191 +22,4 @@ public function test_it_exposes_its_properties() $this->assertSame($command, $tool->command()); $this->assertSame($testCommand, $tool->testCommand()); } - - public function test_it_imports_tool_definition_from_an_array() - { - $tool = Tool::import([ - 'name' => 'phpstan', - 'summary' => 'Static analysis tool', - 'website' => 'https://github.com/phpstan/phpstan', - 'command' => [ - 'composer-bin-plugin' => [ - 'package' => 'phpstan/phpstan', - 'namespace' => 'tools' - ] - ], - 'test' => '/usr/bin/true', - ]); - - $this->assertSame('phpstan', $tool->name()); - $this->assertSame('Static analysis tool', $tool->summary()); - $this->assertSame('https://github.com/phpstan/phpstan', $tool->website()); - $this->assertInstanceOf(Command::class, $tool->command()); - $this->assertInstanceOf(TestCommand::class, $tool->testCommand()); - } - - public function test_it_imports_the_composer_bin_plugin_command() - { - $tool = Tool::import($this->definition([ - 'command' => [ - 'composer-bin-plugin' => [ - 'package' => 'phpstan/phpstan', - 'namespace' => 'tools' - ] - ] - ])); - - $this->assertInstanceOf(ComposerBinPluginCommand::class, $tool->command()); - } - - public function test_it_imports_the_phar_download_command() - { - $tool = Tool::import($this->definition([ - 'command' => [ - 'phar-download' => [ - 'phar' => 'phpstan/phpstan', - 'bin' => 'tools' - ] - ] - ])); - - $this->assertInstanceOf(PharDownloadCommand::class, $tool->command()); - } - - public function test_it_imports_the_file_download_command() - { - $tool = Tool::import($this->definition([ - 'command' => [ - 'file-download' => [ - 'url' => 'http://example.com/file', - 'file' => 'file' - ] - ] - ])); - - $this->assertInstanceOf(FileDownloadCommand::class, $tool->command()); - } - - public function test_it_imports_the_box_build_command() - { - $tool = Tool::import($this->definition([ - 'command' => [ - 'box-build' => [ - 'repository' => 'https://github.com/behat/behat.git', - 'phar' => 'behat.phar', - 'bin' => '/usr/local/bin/behat', - 'version' => 'v3.4.0', - ] - ] - ])); - - $this->assertInstanceOf(BoxBuildCommand::class, $tool->command()); - } - - public function test_it_imports_the_composer_install_command() - { - $tool = Tool::import($this->definition([ - 'command' => [ - 'composer-install' => [ - 'repository' => 'https://github.com/behat/behat.git', - 'version' => 'v3.4.0', - ] - ] - ])); - - $this->assertInstanceOf(ComposerInstallCommand::class, $tool->command()); - } - - public function test_it_imports_the_composer_global_install_command() - { - $tool = Tool::import($this->definition([ - 'command' => [ - 'composer-global-install' => [ - 'package' => 'behat/behat', - 'version' => 'v3.4.0', - ] - ] - ])); - - $this->assertInstanceOf(ComposerGlobalInstallCommand::class, $tool->command()); - } - public function test_it_imports_multiple_commands() - { - $tool = Tool::import($this->definition([ - 'command' => [ - 'phar-download' => [ - 'phar' => 'phpstan/phpstan', - 'bin' => 'tools' - ], - 'file-download' => [ - [ - 'url' => 'http://example.com/file1', - 'file' => 'file1' - ], - [ - 'url' => 'http://example.com/file2', - 'file' => 'file2' - ] - ] - ] - ])); - - $this->assertInstanceOf(MultiStepCommand::class, $tool->command()); - } - - public function test_it_complains_if_it_cannot_recognise_the_command() - { - $this->expectException(\RuntimeException::class); - - Tool::import($this->definition(['command' => ['foo' => ['phar' => 'phpstan/phpstan']]])); - } - - public function test_it_complains_if_the_command_is_empty() - { - $this->expectException(\RuntimeException::class); - - Tool::import($this->definition(['command' => []])); - } - - /** - * @dataProvider provideRequiredProperties - */ - public function test_it_complains_if_any_of_required_properties_is_missing(string $property) - { - $this->expectException(\InvalidArgumentException::class); - - $properties = $this->definition(); - - unset($properties[$property]); - - Tool::import($properties); - } - - public function provideRequiredProperties(): \Generator - { - yield ['name']; - yield ['summary']; - yield ['website']; - yield ['command']; - yield ['test']; - } - - private function definition(array $overrides = []): array - { - return \array_merge( - [ - 'name' => 'phpstan', - 'summary' => 'Static analysis tool', - 'website' => 'https://github.com/phpstan/phpstan', - 'command' => [ - 'composer-bin-plugin' => [ - 'package' => 'phpstan/phpstan', - 'namespace' => 'tools' - ] - ], - 'test' => '/usr/bin/true', - ], - $overrides - ); - } } diff --git a/tests/UseCase/InstallToolsTest.php b/tests/UseCase/InstallToolsTest.php index e6ad75d9..918d6d81 100644 --- a/tests/UseCase/InstallToolsTest.php +++ b/tests/UseCase/InstallToolsTest.php @@ -47,8 +47,8 @@ public function test_it_returns_a_multi_step_command() public function test_it_groups_composer_global_install_commands() { $this->tools->all()->willReturn(Collection::create([ - $this->tool(ComposerGlobalInstallCommand::import(['package' => 'phpstan/phpstan'])), - $this->tool(ComposerGlobalInstallCommand::import(['package' => 'phan/phan'])), + $this->tool(new ComposerGlobalInstallCommand('phpstan/phpstan')), + $this->tool(new ComposerGlobalInstallCommand('phan/phan')), ])); $command = $this->useCase->__invoke(); @@ -59,8 +59,8 @@ public function test_it_groups_composer_global_install_commands() public function test_it_groups_composer_bin_plugin_commands() { $this->tools->all()->willReturn(Collection::create([ - $this->tool(ComposerBinPluginCommand::import(['package' => 'phpstan/phpstan', 'namespace' => 'tools'])), - $this->tool(ComposerBinPluginCommand::import(['package' => 'phan/phan', 'namespace' => 'tools'])), + $this->tool(new ComposerBinPluginCommand('phpstan/phpstan', 'tools')), + $this->tool(new ComposerBinPluginCommand('phan/phan', 'tools')), ])); $command = $this->useCase->__invoke(); @@ -96,7 +96,7 @@ public function test_it_includes_multi_step_commands() public function test_it_includes_composer_install_commands() { $this->tools->all()->willReturn(Collection::create([ - $this->tool(ComposerInstallCommand::import(['repository' => 'git@github.com:phpspec/phpspec.git'])), + $this->tool(new ComposerInstallCommand('git@github.com:phpspec/phpspec.git')), ])); $command = $this->useCase->__invoke(); @@ -107,7 +107,7 @@ public function test_it_includes_composer_install_commands() public function test_it_includes_box_build_commands() { $this->tools->all()->willReturn(Collection::create([ - $this->tool(BoxBuildCommand::import(['repository' => 'https://github.com/behat/behat.git', 'phar' => 'behat.phar', 'bin' => '/tools/behat'])), + $this->tool(new BoxBuildCommand('https://github.com/behat/behat.git', 'behat.phar', '/tools/behat')), ])); $command = $this->useCase->__invoke(); @@ -118,7 +118,7 @@ public function test_it_includes_box_build_commands() public function test_it_includes_phar_download_commands() { $this->tools->all()->willReturn(Collection::create([ - $this->tool(PharDownloadCommand::import(['phar' => 'https://github.com/sensiolabs-de/deptrac/releases/download/0.2.0/deptrac-0.2.0.phar', 'bin' => '/tools/phar'])), + $this->tool(new PharDownloadCommand('https://github.com/sensiolabs-de/deptrac/releases/download/0.2.0/deptrac-0.2.0.phar', '/tools/phar')), ])); $command = $this->useCase->__invoke();