From fb386dee18ec4541a7cc805dd058c3b305e05784 Mon Sep 17 00:00:00 2001 From: Pascal Landau Date: Thu, 3 Jan 2019 16:55:11 +0100 Subject: [PATCH 1/8] 580: Adds support for --tasks option in run command. --- doc/commands.md | 9 +++ spec/Collection/TasksCollectionSpec.php | 27 +++++++++ spec/Runner/TaskRunnerContextSpec.php | 14 +++++ spec/Runner/TaskRunnerSpec.php | 1 + src/Collection/TasksCollection.php | 15 +++++ src/Console/Command/RunCommand.php | 33 ++++++++++- src/Runner/TaskRunner.php | 1 + src/Runner/TaskRunnerContext.php | 28 ++++++++- test/Console/Command/RunCommandTest.php | 78 +++++++++++++++++++++++++ 9 files changed, 202 insertions(+), 4 deletions(-) create mode 100644 test/Console/Command/RunCommandTest.php diff --git a/doc/commands.md b/doc/commands.md index 3d5de5e1c..25d16b4c9 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -42,3 +42,12 @@ php ./vendor/bin/grumphp run --testsuite=mytestsuite This command can also be used for continious integration. More information about the testsuites can be found in the [testsuites documentation](testsuites.md). + +If you want to run only a subset of the configured tasks, you can run the command with the `--tasks` option: + +```sh +php ./vendor/bin/grumphp run --tasks=task1,task2 +``` + +The `--tasks` value has to be a comma-separated string of task names that match the keys in the `tasks` section +of the `grumphp.yml` file. See [#580](https://github.com/phpro/grumphp/issues/580) for a more exhaustive explanation. diff --git a/spec/Collection/TasksCollectionSpec.php b/spec/Collection/TasksCollectionSpec.php index f5581e285..6edcabbec 100644 --- a/spec/Collection/TasksCollectionSpec.php +++ b/spec/Collection/TasksCollectionSpec.php @@ -62,6 +62,33 @@ function it_can_filter_by_empty_testsuite(TaskInterface $task1, TaskInterface $t $tasks[1]->shouldBe($task2); } + function it_can_filter_by_task_names(TaskInterface $task1, TaskInterface $task2) + { + $task1->getName()->willReturn('task1'); + $task2->getName()->willReturn('task2'); + $tasks = ['task1']; + + $result = $this->filterByTaskName($tasks); + $result->shouldBeAnInstanceOf(TasksCollection::class); + $result->count()->shouldBe(1); + $tasks = $result->toArray(); + $tasks[0]->shouldBe($task1); + } + + function it_can_filter_by_empty_task_names(TaskInterface $task1, TaskInterface $task2) + { + $task1->getName()->willReturn('task1'); + $task2->getName()->willReturn('task2'); + $tasks = []; + + $result = $this->filterByTaskName($tasks); + $result->shouldBeAnInstanceOf(TasksCollection::class); + $result->count()->shouldBe(2); + $tasks = $result->toArray(); + $tasks[0]->shouldBe($task1); + $tasks[1]->shouldBe($task2); + } + function it_should_sort_on_priority(TaskInterface $task1, TaskInterface $task2, TaskInterface $task3, GrumPHP $grumPHP) { $this->beConstructedWith([$task1, $task2, $task3]); diff --git a/spec/Runner/TaskRunnerContextSpec.php b/spec/Runner/TaskRunnerContextSpec.php index 0f6a2b22a..53024a401 100644 --- a/spec/Runner/TaskRunnerContextSpec.php +++ b/spec/Runner/TaskRunnerContextSpec.php @@ -37,6 +37,20 @@ function it_has_no_test_suite(ContextInterface $context) $this->getTestSuite()->shouldBe(null); } + function it_has_no_tasks() + { + $this->hasTasks()->shouldBe(false); + $this->getTasks()->shouldBe([]); + } + + function it_has_tasks(ContextInterface $context) + { + $tasks = ["task_1"]; + $this->beConstructedWith($context, null, $tasks); + $this->hasTasks()->shouldBe(true); + $this->getTasks()->shouldBe($tasks); + } + function it_knows_to_skip_the_success_message() { $this->skipSuccessOutput()->shouldBe(false); diff --git a/spec/Runner/TaskRunnerSpec.php b/spec/Runner/TaskRunnerSpec.php index ec6b4db05..ec90f239e 100644 --- a/spec/Runner/TaskRunnerSpec.php +++ b/spec/Runner/TaskRunnerSpec.php @@ -35,6 +35,7 @@ public function let( $runnerContext->getTaskContext()->willReturn($taskContext); $runnerContext->getTestSuite()->willReturn(null); + $runnerContext->getTasks()->willReturn([]); $task1->getName()->willReturn('task1'); $task1->canRunInContext($taskContext)->willReturn(true); diff --git a/src/Collection/TasksCollection.php b/src/Collection/TasksCollection.php index f359af68c..e1ad8e9d0 100644 --- a/src/Collection/TasksCollection.php +++ b/src/Collection/TasksCollection.php @@ -34,6 +34,21 @@ public function filterByTestSuite(TestSuiteInterface $testSuite = null): self }); } + /** + * @param string[] $tasks + * + * @return TasksCollection + */ + public function filterByTaskName($tasks) + { + return $this->filter(function (TaskInterface $task) use ($tasks) { + if (empty($tasks)) { + return true; + } + return in_array($task->getName(), $tasks); + }); + } + /** * This method sorts the tasks by highest priority first. */ diff --git a/src/Console/Command/RunCommand.php b/src/Console/Command/RunCommand.php index 97783b414..623959482 100644 --- a/src/Console/Command/RunCommand.php +++ b/src/Console/Command/RunCommand.php @@ -51,6 +51,13 @@ protected function configure() 'Specify which testsuite you want to run.', null ); + $this->addOption( + 'tasks', + null, + InputOption::VALUE_REQUIRED, + 'Specify which tasks you want to run (comma separated). Example --tasks=task1,task2', + null + ); } public function execute(InputInterface $input, OutputInterface $output) @@ -58,9 +65,12 @@ public function execute(InputInterface $input, OutputInterface $output) $files = $this->getRegisteredFiles(); $testSuites = $this->grumPHP->getTestSuites(); + $tasks = $this->parseCommaSeparatedOption($input->getOption("tasks")); + $context = new TaskRunnerContext( new RunContext($files), - (bool) $input->getOption('testsuite') ? $testSuites->getRequired($input->getOption('testsuite')) : null + (bool) $input->getOption('testsuite') ? $testSuites->getRequired($input->getOption('testsuite')) : null, + $tasks ); return $this->taskRunner()->run($output, $context); @@ -80,4 +90,25 @@ protected function paths(): PathsHelper { return $this->getHelper(PathsHelper::HELPER_NAME); } + + /** + * Split $value on ",", trim the individual parts and + * de-deduplicate the remaining values + * + * @param string $value + * @return string[] + */ + protected function parseCommaSeparatedOption($value) + { + $stringValues = explode(",", $value); + $parsedValues = []; + foreach ($stringValues as $k => $v) { + $v = trim($v); + if (empty($v)) { + continue; + } + $parsedValues[$v] = $v; + } + return $parsedValues; + } } diff --git a/src/Runner/TaskRunner.php b/src/Runner/TaskRunner.php index 6eab357e6..bdde516f4 100644 --- a/src/Runner/TaskRunner.php +++ b/src/Runner/TaskRunner.php @@ -69,6 +69,7 @@ public function run(TaskRunnerContext $runnerContext): TaskResultCollection $tasks = $this->tasks ->filterByContext($runnerContext->getTaskContext()) ->filterByTestSuite($runnerContext->getTestSuite()) + ->filterByTaskName($runnerContext->getTasks()) ->sortByPriority($this->grumPHP); $taskResults = new TaskResultCollection(); diff --git a/src/Runner/TaskRunnerContext.php b/src/Runner/TaskRunnerContext.php index 627c2869b..8314a1073 100644 --- a/src/Runner/TaskRunnerContext.php +++ b/src/Runner/TaskRunnerContext.php @@ -22,15 +22,21 @@ class TaskRunnerContext /** * @var null|TestSuiteInterface */ - private $testSuite = null; + private $testSuite; /** - * TaskRunnerContext constructor. + * @var string[] */ - public function __construct(ContextInterface $taskContext, TestSuiteInterface $testSuite = null) + private $tasks; + + public function __construct(ContextInterface $taskContext, TestSuiteInterface $testSuite = null, array $tasks = null) { $this->taskContext = $taskContext; $this->testSuite = $testSuite; + if($tasks === null){ + $tasks = []; + } + $this->tasks = $tasks; } public function getTaskContext(): ContextInterface @@ -68,4 +74,20 @@ public function setTestSuite(TestSuiteInterface $testSuite) { $this->testSuite = $testSuite; } + + /** + * @return string[] + */ + public function getTasks() + { + return $this->tasks; + } + + /** + * @return bool + */ + public function hasTasks() + { + return !empty($this->tasks); + } } diff --git a/test/Console/Command/RunCommandTest.php b/test/Console/Command/RunCommandTest.php new file mode 100644 index 000000000..1f9ad4d03 --- /dev/null +++ b/test/Console/Command/RunCommandTest.php @@ -0,0 +1,78 @@ +createMock(GrumPHP::class); + /** + * @var RegisteredFiles $registeredFiles + */ + $registeredFiles = $this->createMock(RegisteredFiles::class); + + $command = new RunCommand($grumPhp, $registeredFiles); + $method = new \ReflectionMethod($command, "parseCommaSeparatedOption"); + $method->setAccessible(true); + + $actual = $method->invoke($command, $valueString); + + $this->assertEquals($expected, $actual); + } + + + public function parses_comma_separated_options_dataProvider() + { + return [ + "default" => [ + "valueString" => "foo,bar", + "expected" => [ + "foo" => "foo", + "bar" => "bar" + ], + ], + "trims values" => [ + "valueString" => "foo , bar", + "expected" => [ + "foo" => "foo", + "bar" => "bar" + ], + ], + "deduplicates values" => [ + "valueString" => "foo,bar,bar", + "expected" => [ + "foo" => "foo", + "bar" => "bar" + ], + ], + "null" => [ + "valueString" => null, + "expected" => [], + ], + "empty" => [ + "valueString" => "", + "expected" => [], + ], + "empty after trim" => [ + "valueString" => " ", + "expected" => [], + ], + ]; + } +} From a8c1d89926b304d74ee45d78501d33bdd2b461d8 Mon Sep 17 00:00:00 2001 From: Pascal Landau Date: Thu, 3 Jan 2019 18:28:33 +0100 Subject: [PATCH 2/8] Fixes style. --- src/Runner/TaskRunnerContext.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Runner/TaskRunnerContext.php b/src/Runner/TaskRunnerContext.php index 8314a1073..37121579b 100644 --- a/src/Runner/TaskRunnerContext.php +++ b/src/Runner/TaskRunnerContext.php @@ -33,7 +33,7 @@ public function __construct(ContextInterface $taskContext, TestSuiteInterface $t { $this->taskContext = $taskContext; $this->testSuite = $testSuite; - if($tasks === null){ + if ($tasks === null) { $tasks = []; } $this->tasks = $tasks; From 6a4f2c31ac50ce9adb8301b58b8a3b920ab2ba3e Mon Sep 17 00:00:00 2001 From: Pascal Landau Date: Fri, 4 Jan 2019 10:02:38 +0100 Subject: [PATCH 3/8] Updates #580 to php7.0, removes de-duplication of --tasks option elements --- spec/Collection/TasksCollectionSpec.php | 17 ++++++++- spec/Runner/TaskRunnerContextSpec.php | 6 +-- src/Collection/TasksCollection.php | 15 ++++---- src/Console/Command/RunCommand.php | 10 ++--- src/Runner/TaskRunner.php | 2 +- test/Console/Command/RunCommandTest.php | 51 +++++++++---------------- 6 files changed, 49 insertions(+), 52 deletions(-) diff --git a/spec/Collection/TasksCollectionSpec.php b/spec/Collection/TasksCollectionSpec.php index 6edcabbec..db1974e6f 100644 --- a/spec/Collection/TasksCollectionSpec.php +++ b/spec/Collection/TasksCollectionSpec.php @@ -68,7 +68,20 @@ function it_can_filter_by_task_names(TaskInterface $task1, TaskInterface $task2) $task2->getName()->willReturn('task2'); $tasks = ['task1']; - $result = $this->filterByTaskName($tasks); + $result = $this->filterByTaskNames($tasks); + $result->shouldBeAnInstanceOf(TasksCollection::class); + $result->count()->shouldBe(1); + $tasks = $result->toArray(); + $tasks[0]->shouldBe($task1); + } + + function it_can_filter_by_duplicate_task_names(TaskInterface $task1, TaskInterface $task2) + { + $task1->getName()->willReturn('task1'); + $task2->getName()->willReturn('task2'); + $tasks = ['task1', 'task1']; + + $result = $this->filterByTaskNames($tasks); $result->shouldBeAnInstanceOf(TasksCollection::class); $result->count()->shouldBe(1); $tasks = $result->toArray(); @@ -81,7 +94,7 @@ function it_can_filter_by_empty_task_names(TaskInterface $task1, TaskInterface $ $task2->getName()->willReturn('task2'); $tasks = []; - $result = $this->filterByTaskName($tasks); + $result = $this->filterByTaskNames($tasks); $result->shouldBeAnInstanceOf(TasksCollection::class); $result->count()->shouldBe(2); $tasks = $result->toArray(); diff --git a/spec/Runner/TaskRunnerContextSpec.php b/spec/Runner/TaskRunnerContextSpec.php index 53024a401..94eb94c46 100644 --- a/spec/Runner/TaskRunnerContextSpec.php +++ b/spec/Runner/TaskRunnerContextSpec.php @@ -11,7 +11,7 @@ class TaskRunnerContextSpec extends ObjectBehavior { function let(ContextInterface $context, TestSuiteInterface $testSuite) { - $this->beConstructedWith($context, $testSuite); + $this->beConstructedWith($context, [], $testSuite); } function it_is_initializable() @@ -32,7 +32,7 @@ function it_has_a_test_suite(TestSuiteInterface $testSuite) function it_has_no_test_suite(ContextInterface $context) { - $this->beConstructedWith($context); + $this->beConstructedWith($context, []); $this->hasTestSuite()->shouldBe(false); $this->getTestSuite()->shouldBe(null); } @@ -46,7 +46,7 @@ function it_has_no_tasks() function it_has_tasks(ContextInterface $context) { $tasks = ["task_1"]; - $this->beConstructedWith($context, null, $tasks); + $this->beConstructedWith($context, $tasks); $this->hasTasks()->shouldBe(true); $this->getTasks()->shouldBe($tasks); } diff --git a/src/Collection/TasksCollection.php b/src/Collection/TasksCollection.php index e1ad8e9d0..1676a6bf6 100644 --- a/src/Collection/TasksCollection.php +++ b/src/Collection/TasksCollection.php @@ -36,16 +36,15 @@ public function filterByTestSuite(TestSuiteInterface $testSuite = null): self /** * @param string[] $tasks - * - * @return TasksCollection */ - public function filterByTaskName($tasks) + public function filterByTaskNames($tasks): self { + if (empty($tasks)) { + return new self($this->toArray()); + } + return $this->filter(function (TaskInterface $task) use ($tasks) { - if (empty($tasks)) { - return true; - } - return in_array($task->getName(), $tasks); + return \in_array($task->getName(), $tasks, true); }); } @@ -54,7 +53,7 @@ public function filterByTaskName($tasks) */ public function sortByPriority(GrumPHP $grumPHP): self { - $priorityQueue = new SplPriorityQueue(); + $priorityQueue = new SplPriorityQueue(); $stableSortIndex = PHP_INT_MAX; foreach ($this->getIterator() as $task) { $metadata = $grumPHP->getTaskMetadata($task->getName()); diff --git a/src/Console/Command/RunCommand.php b/src/Console/Command/RunCommand.php index 623959482..77c1a0b27 100644 --- a/src/Console/Command/RunCommand.php +++ b/src/Console/Command/RunCommand.php @@ -65,12 +65,12 @@ public function execute(InputInterface $input, OutputInterface $output) $files = $this->getRegisteredFiles(); $testSuites = $this->grumPHP->getTestSuites(); - $tasks = $this->parseCommaSeparatedOption($input->getOption("tasks")); + $tasks = $this->parseCommaSeparatedOption($input->getOption("tasks") ?? ""); $context = new TaskRunnerContext( new RunContext($files), - (bool) $input->getOption('testsuite') ? $testSuites->getRequired($input->getOption('testsuite')) : null, - $tasks + $tasks, + (bool) $input->getOption('testsuite') ? $testSuites->getRequired($input->getOption('testsuite')) : null ); return $this->taskRunner()->run($output, $context); @@ -98,7 +98,7 @@ protected function paths(): PathsHelper * @param string $value * @return string[] */ - protected function parseCommaSeparatedOption($value) + protected function parseCommaSeparatedOption(string $value) { $stringValues = explode(",", $value); $parsedValues = []; @@ -107,7 +107,7 @@ protected function parseCommaSeparatedOption($value) if (empty($v)) { continue; } - $parsedValues[$v] = $v; + $parsedValues[] = $v; } return $parsedValues; } diff --git a/src/Runner/TaskRunner.php b/src/Runner/TaskRunner.php index bdde516f4..99c773e11 100644 --- a/src/Runner/TaskRunner.php +++ b/src/Runner/TaskRunner.php @@ -69,7 +69,7 @@ public function run(TaskRunnerContext $runnerContext): TaskResultCollection $tasks = $this->tasks ->filterByContext($runnerContext->getTaskContext()) ->filterByTestSuite($runnerContext->getTestSuite()) - ->filterByTaskName($runnerContext->getTasks()) + ->filterByTaskNames($runnerContext->getTasks()) ->sortByPriority($this->grumPHP); $taskResults = new TaskResultCollection(); diff --git a/test/Console/Command/RunCommandTest.php b/test/Console/Command/RunCommandTest.php index 1f9ad4d03..5b4d62778 100644 --- a/test/Console/Command/RunCommandTest.php +++ b/test/Console/Command/RunCommandTest.php @@ -2,36 +2,32 @@ namespace GrumPHPTest\Console\Command; -use GrumPHP\Configuration\GrumPHP; use GrumPHP\Console\Command\RunCommand; -use GrumPHP\Locator\RegisteredFiles; use PHPUnit\Framework\TestCase; class RunCommandTest extends TestCase { /** * @test - * @param null $valueString - * @param null $expected + * @param string $valueString + * @param array $expected * @dataProvider parses_comma_separated_options_dataProvider - * @throws \ReflectionException */ - function parses_comma_separated_options($valueString = null, $expected = null) + function parses_comma_separated_options(string $valueString, array $expected) { - /** - * @var GrumPHP $grumPhp - */ - $grumPhp = $this->createMock(GrumPHP::class); - /** - * @var RegisteredFiles $registeredFiles - */ - $registeredFiles = $this->createMock(RegisteredFiles::class); + $command = new class extends RunCommand{ + public function __construct() + { + } - $command = new RunCommand($grumPhp, $registeredFiles); - $method = new \ReflectionMethod($command, "parseCommaSeparatedOption"); - $method->setAccessible(true); + public function parseCommaSeparatedOption($str) + { + return parent::parseCommaSeparatedOption(... func_get_args()); + } + }; - $actual = $method->invoke($command, $valueString); + $actual = $command->parseCommaSeparatedOption($valueString); + $actual = array_values($actual); $this->assertEquals($expected, $actual); } @@ -43,28 +39,17 @@ public function parses_comma_separated_options_dataProvider() "default" => [ "valueString" => "foo,bar", "expected" => [ - "foo" => "foo", - "bar" => "bar" + "foo", + "bar" ], ], "trims values" => [ "valueString" => "foo , bar", "expected" => [ - "foo" => "foo", - "bar" => "bar" + "foo", + "bar" ], ], - "deduplicates values" => [ - "valueString" => "foo,bar,bar", - "expected" => [ - "foo" => "foo", - "bar" => "bar" - ], - ], - "null" => [ - "valueString" => null, - "expected" => [], - ], "empty" => [ "valueString" => "", "expected" => [], From a8c91e1a005895a5e893216598300ab9b5f5c09b Mon Sep 17 00:00:00 2001 From: Lander Vanderstraeten Date: Fri, 19 Apr 2019 13:08:28 +0200 Subject: [PATCH 4/8] Refactor --- spec/Runner/TaskRunnerContextSpec.php | 8 ++++---- src/Console/Command/RunCommand.php | 4 ++-- src/Runner/TaskRunnerContext.php | 21 +++++++++------------ 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/spec/Runner/TaskRunnerContextSpec.php b/spec/Runner/TaskRunnerContextSpec.php index 94eb94c46..9ddb8902a 100644 --- a/spec/Runner/TaskRunnerContextSpec.php +++ b/spec/Runner/TaskRunnerContextSpec.php @@ -11,7 +11,7 @@ class TaskRunnerContextSpec extends ObjectBehavior { function let(ContextInterface $context, TestSuiteInterface $testSuite) { - $this->beConstructedWith($context, [], $testSuite); + $this->beConstructedWith($context, $testSuite); } function it_is_initializable() @@ -32,7 +32,7 @@ function it_has_a_test_suite(TestSuiteInterface $testSuite) function it_has_no_test_suite(ContextInterface $context) { - $this->beConstructedWith($context, []); + $this->beConstructedWith($context); $this->hasTestSuite()->shouldBe(false); $this->getTestSuite()->shouldBe(null); } @@ -43,10 +43,10 @@ function it_has_no_tasks() $this->getTasks()->shouldBe([]); } - function it_has_tasks(ContextInterface $context) + function it_has_tasks(ContextInterface $context, TestSuiteInterface $testSuite) { $tasks = ["task_1"]; - $this->beConstructedWith($context, $tasks); + $this->beConstructedWith($context, $testSuite, $tasks); $this->hasTasks()->shouldBe(true); $this->getTasks()->shouldBe($tasks); } diff --git a/src/Console/Command/RunCommand.php b/src/Console/Command/RunCommand.php index 77c1a0b27..389d3977f 100644 --- a/src/Console/Command/RunCommand.php +++ b/src/Console/Command/RunCommand.php @@ -69,8 +69,8 @@ public function execute(InputInterface $input, OutputInterface $output) $context = new TaskRunnerContext( new RunContext($files), - $tasks, - (bool) $input->getOption('testsuite') ? $testSuites->getRequired($input->getOption('testsuite')) : null + (bool) $input->getOption('testsuite') ? $testSuites->getRequired($input->getOption('testsuite')) : null, + $tasks ); return $this->taskRunner()->run($output, $context); diff --git a/src/Runner/TaskRunnerContext.php b/src/Runner/TaskRunnerContext.php index 37121579b..5cbe773c8 100644 --- a/src/Runner/TaskRunnerContext.php +++ b/src/Runner/TaskRunnerContext.php @@ -29,13 +29,13 @@ class TaskRunnerContext */ private $tasks; - public function __construct(ContextInterface $taskContext, TestSuiteInterface $testSuite = null, array $tasks = null) - { + public function __construct( + ContextInterface $taskContext, + TestSuiteInterface $testSuite = null, + array $tasks = [] + ) { $this->taskContext = $taskContext; $this->testSuite = $testSuite; - if ($tasks === null) { - $tasks = []; - } $this->tasks = $tasks; } @@ -60,7 +60,7 @@ public function hasTestSuite(): bool } /** - * @return TestSuiteInterface|null + * @return null|TestSuiteInterface */ public function getTestSuite() { @@ -68,7 +68,7 @@ public function getTestSuite() } /** - * @param TestSuiteInterface|null $testSuite + * @param null|TestSuiteInterface $testSuite */ public function setTestSuite(TestSuiteInterface $testSuite) { @@ -78,15 +78,12 @@ public function setTestSuite(TestSuiteInterface $testSuite) /** * @return string[] */ - public function getTasks() + public function getTasks(): array { return $this->tasks; } - /** - * @return bool - */ - public function hasTasks() + public function hasTasks(): bool { return !empty($this->tasks); } From 78efed22c66637121660bba6c5a1e86d7c2e722f Mon Sep 17 00:00:00 2001 From: Lander Vanderstraeten Date: Fri, 19 Apr 2019 13:18:44 +0200 Subject: [PATCH 5/8] Add missing typehint --- src/Collection/TasksCollection.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Collection/TasksCollection.php b/src/Collection/TasksCollection.php index 1676a6bf6..e836cbb70 100644 --- a/src/Collection/TasksCollection.php +++ b/src/Collection/TasksCollection.php @@ -37,7 +37,7 @@ public function filterByTestSuite(TestSuiteInterface $testSuite = null): self /** * @param string[] $tasks */ - public function filterByTaskNames($tasks): self + public function filterByTaskNames(array $tasks): self { if (empty($tasks)) { return new self($this->toArray()); @@ -53,7 +53,7 @@ public function filterByTaskNames($tasks): self */ public function sortByPriority(GrumPHP $grumPHP): self { - $priorityQueue = new SplPriorityQueue(); + $priorityQueue = new SplPriorityQueue(); $stableSortIndex = PHP_INT_MAX; foreach ($this->getIterator() as $task) { $metadata = $grumPHP->getTaskMetadata($task->getName()); From 5090669619988adaa2363b99ebe5e2d8a6b86f7c Mon Sep 17 00:00:00 2001 From: Lander Vanderstraeten Date: Fri, 19 Apr 2019 13:42:58 +0200 Subject: [PATCH 6/8] Refactor --- spec/Util/StrSpec.php | 24 ++++++++++++++++++++++++ src/Console/Command/RunCommand.php | 24 ++---------------------- src/Util/Str.php | 13 ++++++++++++- 3 files changed, 38 insertions(+), 23 deletions(-) create mode 100644 spec/Util/StrSpec.php diff --git a/spec/Util/StrSpec.php b/spec/Util/StrSpec.php new file mode 100644 index 000000000..fcf1577c8 --- /dev/null +++ b/spec/Util/StrSpec.php @@ -0,0 +1,24 @@ +shouldBe(true); + $this::containsOneOf('a;randomText-written by me', ['Text'])->shouldBe(true); + + $this::containsOneOf('a;randomText-written by me', ['this does not exist'])->shouldBe(false); + $this::containsOneOf('a;randomText-written by me', ['text'])->shouldBe(false); + } + + function it_should_split_a_string_by_a_delimiter_and_result_in_a_unique_list() + { + $this::explodeWithCleanup(',', ' a random,list, of things ')->shouldBe([ + 'a random', 'list', 'of things' + ]); + } +} diff --git a/src/Console/Command/RunCommand.php b/src/Console/Command/RunCommand.php index 389d3977f..5e8ee9632 100644 --- a/src/Console/Command/RunCommand.php +++ b/src/Console/Command/RunCommand.php @@ -11,6 +11,7 @@ use GrumPHP\Locator\RegisteredFiles; use GrumPHP\Runner\TaskRunnerContext; use GrumPHP\Task\Context\RunContext; +use GrumPHP\Util\Str; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -65,7 +66,7 @@ public function execute(InputInterface $input, OutputInterface $output) $files = $this->getRegisteredFiles(); $testSuites = $this->grumPHP->getTestSuites(); - $tasks = $this->parseCommaSeparatedOption($input->getOption("tasks") ?? ""); + $tasks = Str::explodeWithCleanup(',', $input->getOption("tasks") ?? ''); $context = new TaskRunnerContext( new RunContext($files), @@ -90,25 +91,4 @@ protected function paths(): PathsHelper { return $this->getHelper(PathsHelper::HELPER_NAME); } - - /** - * Split $value on ",", trim the individual parts and - * de-deduplicate the remaining values - * - * @param string $value - * @return string[] - */ - protected function parseCommaSeparatedOption(string $value) - { - $stringValues = explode(",", $value); - $parsedValues = []; - foreach ($stringValues as $k => $v) { - $v = trim($v); - if (empty($v)) { - continue; - } - $parsedValues[] = $v; - } - return $parsedValues; - } } diff --git a/src/Util/Str.php b/src/Util/Str.php index 9ec961dd4..aeb198ad4 100644 --- a/src/Util/Str.php +++ b/src/Util/Str.php @@ -2,7 +2,7 @@ namespace GrumPHP\Util; -class Str +final class Str { /** * String contains one of the provided needles @@ -17,4 +17,15 @@ public static function containsOneOf(string $haystack, array $needles): bool return false; } + + /** + * Split $value on ",", trim the individual parts and + * de-deduplicate the remaining values + */ + public static function explodeWithCleanup(string $delimiter, string $value): array + { + return array_unique(array_map(function (string $value) { + return trim($value); + }, explode($delimiter, $value))); + } } From e3fc41dd5f0bd5c953b0ce263e5b0738f06c8f0a Mon Sep 17 00:00:00 2001 From: Lander Vanderstraeten Date: Fri, 19 Apr 2019 14:43:23 +0200 Subject: [PATCH 7/8] Refactor --- src/Collection/TasksCollection.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Collection/TasksCollection.php b/src/Collection/TasksCollection.php index e836cbb70..84307f8c1 100644 --- a/src/Collection/TasksCollection.php +++ b/src/Collection/TasksCollection.php @@ -26,7 +26,7 @@ public function filterByContext(ContextInterface $context): self public function filterByTestSuite(TestSuiteInterface $testSuite = null): self { if (null === $testSuite) { - return new self($this->toArray()); + return $this; } return $this->filter(function (TaskInterface $task) use ($testSuite) { @@ -40,7 +40,7 @@ public function filterByTestSuite(TestSuiteInterface $testSuite = null): self public function filterByTaskNames(array $tasks): self { if (empty($tasks)) { - return new self($this->toArray()); + return $this; } return $this->filter(function (TaskInterface $task) use ($tasks) { From 83327e19dd50befb25a482cc110bf5010631561c Mon Sep 17 00:00:00 2001 From: Lander Vanderstraeten Date: Thu, 16 May 2019 13:14:22 +0200 Subject: [PATCH 8/8] Delete test --- test/Console/Command/RunCommandTest.php | 63 ------------------------- 1 file changed, 63 deletions(-) delete mode 100644 test/Console/Command/RunCommandTest.php diff --git a/test/Console/Command/RunCommandTest.php b/test/Console/Command/RunCommandTest.php deleted file mode 100644 index 5b4d62778..000000000 --- a/test/Console/Command/RunCommandTest.php +++ /dev/null @@ -1,63 +0,0 @@ -parseCommaSeparatedOption($valueString); - $actual = array_values($actual); - - $this->assertEquals($expected, $actual); - } - - - public function parses_comma_separated_options_dataProvider() - { - return [ - "default" => [ - "valueString" => "foo,bar", - "expected" => [ - "foo", - "bar" - ], - ], - "trims values" => [ - "valueString" => "foo , bar", - "expected" => [ - "foo", - "bar" - ], - ], - "empty" => [ - "valueString" => "", - "expected" => [], - ], - "empty after trim" => [ - "valueString" => " ", - "expected" => [], - ], - ]; - } -}