Skip to content

Commit

Permalink
phpro#580: Adds support for --tasks option in run command.
Browse files Browse the repository at this point in the history
  • Loading branch information
Pascal Landau committed Jan 3, 2019
1 parent a0f13bd commit 472471f
Show file tree
Hide file tree
Showing 9 changed files with 202 additions and 3 deletions.
9 changes: 9 additions & 0 deletions doc/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
27 changes: 27 additions & 0 deletions spec/Collection/TasksCollectionSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand Down
14 changes: 14 additions & 0 deletions spec/Runner/TaskRunnerContextSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions spec/Runner/TaskRunnerSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
15 changes: 15 additions & 0 deletions src/Collection/TasksCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,21 @@ public function filterByTestSuite(TestSuiteInterface $testSuite = null)
});
}

/**
* @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.
*
Expand Down
33 changes: 32 additions & 1 deletion src/Console/Command/RunCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,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
);
}

/**
Expand All @@ -66,9 +73,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);
Expand Down Expand Up @@ -97,4 +107,25 @@ protected function paths()
{
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;
}
}
1 change: 1 addition & 0 deletions src/Runner/TaskRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ public function run(TaskRunnerContext $runnerContext)
$tasks = $this->tasks
->filterByContext($runnerContext->getTaskContext())
->filterByTestSuite($runnerContext->getTestSuite())
->filterByTaskName($runnerContext->getTasks())
->sortByPriority($this->grumPHP);
$taskResults = new TaskResultCollection();

Expand Down
27 changes: 25 additions & 2 deletions src/Runner/TaskRunnerContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,23 @@ class TaskRunnerContext
*/
private $testSuite = null;

/**
* @var string[]
*/
private $tasks = null;

/**
* TaskRunnerContext constructor.
*
* @param ContextInterface $taskContext
* @param ContextInterface $taskContext
* @param TestSuiteInterface $testSuite
* @param string[]|null $tasks
*/
public function __construct(ContextInterface $taskContext, TestSuiteInterface $testSuite = null)
public function __construct(ContextInterface $taskContext, TestSuiteInterface $testSuite = null, $tasks = null)
{
$this->taskContext = $taskContext;
$this->testSuite = $testSuite;
$this->tasks = $tasks ?? [];
}

/**
Expand Down Expand Up @@ -81,4 +88,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);
}
}
78 changes: 78 additions & 0 deletions test/Console/Command/RunCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

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
* @dataProvider parses_comma_separated_options_dataProvider
* @throws \ReflectionException
*/
function parses_comma_separated_options($valueString = null, $expected = null)
{
/**
* @var GrumPHP $grumPhp
*/
$grumPhp = $this->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" => [],
],
];
}
}

0 comments on commit 472471f

Please sign in to comment.