-
Notifications
You must be signed in to change notification settings - Fork 430
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #558 from Landerstraeten/phpunit-bridge
Add phpunit bridge
- Loading branch information
Showing
7 changed files
with
276 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -110,6 +110,7 @@ parameters: | |
phpspec: ~ | ||
phpstan: ~ | ||
phpunit: ~ | ||
phpunitbridge: ~ | ||
phpversion: ~ | ||
progpilot: ~ | ||
psalm: ~ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# Phpunit bridge | ||
|
||
The Phpunit Bridge task will run your unit tests thanks to the Symfony Phpunit Bridge. | ||
|
||
***Composer*** | ||
|
||
``` | ||
composer require --dev symfony/phpunit-bridge | ||
``` | ||
|
||
***Config*** | ||
|
||
The task lives under the `phpunitbridge` namespace and has following configurable parameters: | ||
|
||
```yaml | ||
# grumphp.yml | ||
parameters: | ||
tasks: | ||
phpunitbridge: | ||
config_file: ~ | ||
testsuite: ~ | ||
group: [] | ||
always_execute: false | ||
``` | ||
**config_file** | ||
*Default: null* | ||
If your phpunit.xml file is located at an exotic location, you can specify your custom config file location with this option. | ||
This option is set to `null` by default. | ||
This means that `phpunit.xml` or `phpunit.xml.dist` are automatically loaded if one of them exist in the current directory. | ||
|
||
|
||
**testsuite** | ||
|
||
*Default: null* | ||
|
||
If you wish to only run tests from a certain Suite. | ||
`testsuite: unit` | ||
|
||
|
||
**group** | ||
|
||
*Default: array()* | ||
|
||
If you wish to only run tests from a certain Group. | ||
`group: [fast,quick,small]` | ||
|
||
|
||
**always_execute** | ||
|
||
*Default: false* | ||
|
||
Always run the whole test suite, even if no PHP files were changed. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
<?php | ||
|
||
namespace spec\GrumPHP\Task; | ||
|
||
use GrumPHP\Collection\FilesCollection; | ||
use GrumPHP\Collection\ProcessArgumentsCollection; | ||
use GrumPHP\Configuration\GrumPHP; | ||
use GrumPHP\Formatter\ProcessFormatterInterface; | ||
use GrumPHP\Process\ProcessBuilder; | ||
use GrumPHP\Runner\TaskResult; | ||
use GrumPHP\Runner\TaskResultInterface; | ||
use GrumPHP\Task\Context\ContextInterface; | ||
use GrumPHP\Task\Context\GitPreCommitContext; | ||
use GrumPHP\Task\Context\RunContext; | ||
use GrumPHP\Task\Phpunit; | ||
use GrumPHP\Task\PhpunitBridge; | ||
use PhpSpec\ObjectBehavior; | ||
use Symfony\Component\Finder\SplFileInfo; | ||
use Symfony\Component\OptionsResolver\OptionsResolver; | ||
use Symfony\Component\Process\Process; | ||
|
||
class PhpunitBridgeSpec extends ObjectBehavior | ||
{ | ||
function let(GrumPHP $grumPHP, ProcessBuilder $processBuilder, ProcessFormatterInterface $formatter) | ||
{ | ||
$grumPHP->getTaskConfiguration('phpunitbridge')->willReturn([]); | ||
$this->beConstructedWith($grumPHP, $processBuilder, $formatter); | ||
} | ||
|
||
function it_is_initializable() | ||
{ | ||
$this->shouldHaveType(PhpunitBridge::class); | ||
} | ||
|
||
function it_should_have_a_name() | ||
{ | ||
$this->getName()->shouldBe('phpunitbridge'); | ||
} | ||
|
||
function it_should_have_configurable_options() | ||
{ | ||
$options = $this->getConfigurableOptions(); | ||
$options->shouldBeAnInstanceOf(OptionsResolver::class); | ||
$options->getDefinedOptions()->shouldContain('config_file'); | ||
$options->getDefinedOptions()->shouldContain('testsuite'); | ||
$options->getDefinedOptions()->shouldContain('group'); | ||
$options->getDefinedOptions()->shouldContain('always_execute'); | ||
} | ||
|
||
function it_should_run_in_git_pre_commit_context(GitPreCommitContext $context) | ||
{ | ||
$this->canRunInContext($context)->shouldReturn(true); | ||
} | ||
|
||
function it_should_run_in_run_context(RunContext $context) | ||
{ | ||
$this->canRunInContext($context)->shouldReturn(true); | ||
} | ||
|
||
function it_does_not_do_anything_if_there_are_no_files(ProcessBuilder $processBuilder, ContextInterface $context) | ||
{ | ||
$processBuilder->buildProcess('phpunitbridge')->shouldNotBeCalled(); | ||
$processBuilder->buildProcess()->shouldNotBeCalled(); | ||
$context->getFiles()->willReturn(new FilesCollection()); | ||
|
||
$result = $this->run($context); | ||
$result->shouldBeAnInstanceOf(TaskResultInterface::class); | ||
$result->getResultCode()->shouldBe(TaskResult::SKIPPED); | ||
} | ||
|
||
function it_runs_if_there_are_no_files_but_always_execute_is_passed(GrumPHP $grumPHP, Process $process, ProcessBuilder $processBuilder, ContextInterface $context) | ||
{ | ||
$grumPHP->getTaskConfiguration('phpunitbridge')->willReturn([ | ||
'always_execute' => true, | ||
]); | ||
|
||
$arguments = new ProcessArgumentsCollection(); | ||
$processBuilder->createArgumentsForCommand('simple-phpunit')->willReturn($arguments); | ||
$processBuilder->buildProcess($arguments)->willReturn($process); | ||
|
||
$process->run()->shouldBeCalled(); | ||
$process->isSuccessful()->willReturn(true); | ||
|
||
$context->getFiles()->willReturn(new FilesCollection()); | ||
|
||
$result = $this->run($context); | ||
$result->shouldBeAnInstanceOf(TaskResultInterface::class); | ||
$result->isPassed()->shouldBe(true); | ||
} | ||
|
||
function it_runs_the_suite(ProcessBuilder $processBuilder, Process $process, ContextInterface $context) | ||
{ | ||
$arguments = new ProcessArgumentsCollection(); | ||
$processBuilder->createArgumentsForCommand('simple-phpunit')->willReturn($arguments); | ||
$processBuilder->buildProcess($arguments)->willReturn($process); | ||
|
||
$process->run()->shouldBeCalled(); | ||
$process->isSuccessful()->willReturn(true); | ||
|
||
$context->getFiles()->willReturn(new FilesCollection([ | ||
new SplFileInfo('test.php', '.', 'test.php') | ||
])); | ||
|
||
$result = $this->run($context); | ||
$result->shouldBeAnInstanceOf(TaskResultInterface::class); | ||
$result->isPassed()->shouldBe(true); | ||
} | ||
|
||
function it_throws_exception_if_the_process_fails(ProcessBuilder $processBuilder, Process $process, ContextInterface $context) | ||
{ | ||
$arguments = new ProcessArgumentsCollection(); | ||
$processBuilder->createArgumentsForCommand('simple-phpunit')->willReturn($arguments); | ||
$processBuilder->buildProcess($arguments)->willReturn($process); | ||
|
||
$process->run()->shouldBeCalled(); | ||
$process->isSuccessful()->willReturn(false); | ||
|
||
$context->getFiles()->willReturn(new FilesCollection([ | ||
new SplFileInfo('test.php', '.', 'test.php') | ||
])); | ||
|
||
$result = $this->run($context); | ||
$result->shouldBeAnInstanceOf(TaskResultInterface::class); | ||
$result->isPassed()->shouldBe(false); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
<?php | ||
|
||
namespace GrumPHP\Task; | ||
|
||
use GrumPHP\Runner\TaskResult; | ||
use GrumPHP\Task\Context\ContextInterface; | ||
use GrumPHP\Task\Context\GitPreCommitContext; | ||
use GrumPHP\Task\Context\RunContext; | ||
use Symfony\Component\OptionsResolver\OptionsResolver; | ||
|
||
/** | ||
* PhpunitBridge task | ||
* | ||
* @link https://symfony.com/doc/current/components/phpunit_bridge.html | ||
*/ | ||
class PhpunitBridge extends AbstractExternalTask | ||
{ | ||
/** | ||
* @return string | ||
*/ | ||
public function getName() | ||
{ | ||
return 'phpunitbridge'; | ||
} | ||
|
||
/** | ||
* @return OptionsResolver | ||
*/ | ||
public function getConfigurableOptions() | ||
{ | ||
$resolver = new OptionsResolver(); | ||
$resolver->setDefaults([ | ||
'config_file' => null, | ||
'testsuite' => null, | ||
'group' => [], | ||
'always_execute' => false, | ||
]); | ||
|
||
$resolver->addAllowedTypes('config_file', ['null', 'string']); | ||
$resolver->addAllowedTypes('testsuite', ['null', 'string']); | ||
$resolver->addAllowedTypes('group', ['array']); | ||
$resolver->addAllowedTypes('always_execute', ['bool']); | ||
|
||
return $resolver; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function canRunInContext(ContextInterface $context) | ||
{ | ||
return ($context instanceof GitPreCommitContext || $context instanceof RunContext); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function run(ContextInterface $context) | ||
{ | ||
$config = $this->getConfiguration(); | ||
|
||
$files = $context->getFiles()->name('*.php'); | ||
if (0 === count($files) && !$config['always_execute']) { | ||
return TaskResult::createSkipped($this, $context); | ||
} | ||
|
||
$arguments = $this->processBuilder->createArgumentsForCommand('simple-phpunit'); | ||
$arguments->addOptionalArgument('--configuration=%s', $config['config_file']); | ||
$arguments->addOptionalArgument('--testsuite=%s', $config['testsuite']); | ||
$arguments->addOptionalCommaSeparatedArgument('--group=%s', $config['group']); | ||
|
||
$process = $this->processBuilder->buildProcess($arguments); | ||
$process->run(); | ||
|
||
if (!$process->isSuccessful()) { | ||
return TaskResult::createFailed($this, $context, $this->formatter->format($process)); | ||
} | ||
|
||
return TaskResult::createPassed($this, $context); | ||
} | ||
} |