Skip to content

Commit

Permalink
Allows phpstormhelper to handle and account for coverage options (#686)
Browse files Browse the repository at this point in the history
* Allows phpstormhelper to handle and account for coverage options

* Use search functions instead of assuming position of arguments
Put test case arguments in expected order
Directly require symfony polyfill for php8.0 function

* Update README.md to indicate additional configuration needed for coverage with PHPStorm

* Sort composer reqs, add config option to auto-sort in the future

* Add compatibility with PHP 7.3

* Ensure test name is a string

Co-authored-by: Filippo Tessarotto <[email protected]>
  • Loading branch information
billypoke and Slamdunk authored Aug 22, 2022
1 parent 994f983 commit 5249af4
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 10 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,11 @@ ParaTest provides a dedicated binary to work with PHPStorm; follow these steps t
You should now have a `ParaTest` run within your configurations list.
It should natively work with the `Rerun failed tests` and `Toggle auto-test` buttons of the `Run` overlay.

### Run with Coverage

Coverage with one of the [available coverage engines](#code-coverage) must already be [configured in PHPStorm](https://www.jetbrains.com/help/phpstorm/code-coverage.html)
and working when running tests sequentially in order for the helper binary to correctly handle code coverage

# For Contributors: testing ParaTest itself

Before creating a Pull Request be sure to run all the necessary checks with `make` command.
6 changes: 4 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"phpunit/phpunit": "^9.5.21",
"sebastian/environment": "^5.1.4",
"symfony/console": "^5.4.9 || ^6.1.2",
"symfony/polyfill-php80": "^v1.26.0",
"symfony/process": "^5.4.8 || ^6.1.0"
},
"require-dev": {
Expand All @@ -55,7 +56,7 @@
"malukenho/mcbumpface": "^1.1.5",
"squizlabs/php_codesniffer": "^3.7.1",
"symfony/filesystem": "^5.4.9 || ^6.1.0",
"vimeo/psalm": "^4.24.0"
"vimeo/psalm": "^4.26.0"
},
"autoload": {
"psr-4": {
Expand All @@ -80,6 +81,7 @@
"dealerdirect/phpcodesniffer-composer-installer": true,
"infection/extension-installer": true,
"malukenho/mcbumpface": true
}
},
"sort-packages": true
}
}
55 changes: 51 additions & 4 deletions src/Util/PhpstormHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,38 @@

namespace ParaTest\Util;

use RuntimeException;

use function array_search;
use function array_unshift;
use function in_array;
use function str_ends_with;

/**
* @internal
*/
final class PhpstormHelper
{
/**
* @param array<int, string> $argv
* @param array<int, string> $argv
*/
public static function handleArgvFromPhpstorm(array &$argv, string $paratestBinary): string
{
$phpunitKey = self::getArgvKeyFor($argv, 'vendor/phpunit/phpunit/phpunit');

if (! in_array('--filter', $argv, true)) {
unset($argv[1]);
$coverageArgKey = self::getCoverageArgvKey($argv);
if ($coverageArgKey !== false) {
unset($argv[$coverageArgKey]);
}

unset($argv[$phpunitKey]);

return $paratestBinary;
}

unset($argv[0]);
$phpunitBinary = $argv[1];
unset($argv[self::getArgvKeyFor($argv, 'vendor/brianium/paratest/bin/paratest')]);
$phpunitBinary = $argv[$phpunitKey];
foreach ($argv as $index => $value) {
if ($value === '--configuration' || $value === '--bootstrap') {
break;
Expand All @@ -37,4 +48,40 @@ public static function handleArgvFromPhpstorm(array &$argv, string $paratestBina

return $phpunitBinary;
}

/**
* @param array<int, string> $argv
*/
private static function getArgvKeyFor(array $argv, string $searchFor): int
{
foreach ($argv as $key => $arg) {
if (str_ends_with($arg, $searchFor)) {
return $key;
}
}

throw new RuntimeException("Missing path to '$searchFor'");
}

/**
* @param array<int, string> $argv
*
* @return int|false
*/
private static function getCoverageArgvKey(array $argv)
{
$coverageOptions = [
'-dpcov.enabled=1',
'-dxdebug.mode=coverage',
];

foreach ($coverageOptions as $coverageOption) {
$key = array_search($coverageOption, $argv, true);
if ($key !== false) {
return $key;
}
}

return false;
}
}
2 changes: 1 addition & 1 deletion test/Unit/Coverage/CoverageReporterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ private function createCoverageReporter(string $fixtureFile): void
$codeCoverage = new CodeCoverage((new Selector())->forLineCoverage($filter), $filter);
$codeCoverage->append(RawCodeCoverageData::fromXdebugWithoutPathCoverage([
__FILE__ => [__LINE__ => 1],
]), uniqid());
]), uniqid('test_'));

$configuration = (new Loader())->load($this->fixture($fixtureFile));

Expand Down
90 changes: 87 additions & 3 deletions test/Unit/Util/PhpstormHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use PHPUnit\Framework\TestCase;

use function array_values;
use function sprintf;
use function uniqid;

/**
Expand All @@ -33,14 +34,14 @@ public function testWithoutFilterRunParaTest(
$actualBinary = PhpstormHelper::handleArgvFromPhpstorm($argv, $paratestBinary);
$argv = array_values($argv);

static::assertSame($expectedArgv, $argv);
self::assertSame($expectedArgv, $argv);
self::assertSame($expectedBinary, $actualBinary);
}

public function providePhpstormCases(): Generator
{
$paratestBinary = uniqid('paratest_');
$phpunitBinary = uniqid('phpunit_');
$paratestBinary = sprintf('%s/vendor/brianium/paratest/bin/paratest', uniqid());
$phpunitBinary = sprintf('%s/vendor/phpunit/phpunit/phpunit', uniqid());

$argv = [];
$argv[] = $paratestBinary;
Expand Down Expand Up @@ -94,5 +95,88 @@ public function providePhpstormCases(): Generator
$paratestBinary,
$phpunitBinary,
];

$argv = [];
$argv[] = $paratestBinary;
$argv[] = '-dxdebug.mode=coverage';
$argv[] = $phpunitBinary;
$argv[] = '--runner';
$argv[] = 'WrapperRunner';
$argv[] = '--coverage-clover';
$argv[] = '/home/user/repos/test/coverage.xml';
$argv[] = '--configuration';
$argv[] = '/home/user/repos/test/phpunit.xml';
$argv[] = '--teamcity';

$expected = [];
$expected[] = $paratestBinary;
$expected[] = '--runner';
$expected[] = 'WrapperRunner';
$expected[] = '--coverage-clover';
$expected[] = '/home/user/repos/test/coverage.xml';
$expected[] = '--configuration';
$expected[] = '/home/user/repos/test/phpunit.xml';
$expected[] = '--teamcity';

yield 'with -dxdebug.mode=coverage run ParaTest' => [
$argv,
$expected,
$paratestBinary,
$paratestBinary,
];

$argv = [];
$argv[] = $paratestBinary;
$argv[] = '-dxdebug.mode=coverage';
$argv[] = $phpunitBinary;
$argv[] = '--coverage-clover';
$argv[] = '/home/user/repos/test/coverage.xml';
$argv[] = '--configuration';
$argv[] = '/home/user/repos/test/phpunit.xml';
$argv[] = '--teamcity';

$expected = [];
$expected[] = $paratestBinary;
$expected[] = '--coverage-clover';
$expected[] = '/home/user/repos/test/coverage.xml';
$expected[] = '--configuration';
$expected[] = '/home/user/repos/test/phpunit.xml';
$expected[] = '--teamcity';

yield 'with -dxdebug.mode=coverage and no wrapper run ParaTest' => [
$argv,
$expected,
$paratestBinary,
$paratestBinary,
];

$argv = [];
$argv[] = $paratestBinary;
$argv[] = '-dpcov.enabled=1';
$argv[] = $phpunitBinary;
$argv[] = '--runner';
$argv[] = 'WrapperRunner';
$argv[] = '--coverage-clover';
$argv[] = '/home/user/repos/test/coverage.xml';
$argv[] = '--configuration';
$argv[] = '/home/user/repos/test/phpunit.xml';
$argv[] = '--teamcity';

$expected = [];
$expected[] = $paratestBinary;
$expected[] = '--runner';
$expected[] = 'WrapperRunner';
$expected[] = '--coverage-clover';
$expected[] = '/home/user/repos/test/coverage.xml';
$expected[] = '--configuration';
$expected[] = '/home/user/repos/test/phpunit.xml';
$expected[] = '--teamcity';

yield 'with -dpcov.enabled=1 run ParaTest' => [
$argv,
$expected,
$paratestBinary,
$paratestBinary,
];
}
}

0 comments on commit 5249af4

Please sign in to comment.