Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 9 additions & 18 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,6 @@ jobs:
XDEBUG_MODE: coverage
run: composer check

-
name: Output line coverage
run: head cache/coverage/coverage.txt | grep Lines

-
name: Report patch coverage
if: github.event_name == 'pull_request'
run: |
if git diff --name-only ${{ github.event.pull_request.base.sha }} | grep -q '\.php$'; then
git diff ${{ github.event.pull_request.base.sha }} > changes.patch
vendor/bin/phpcov patch-coverage --path-prefix $(pwd) cache/coverage/coverage.cov changes.patch || true
else
echo "No PHP files changed, skipping patch coverage report"
fi

cda:
runs-on: ubuntu-latest
strategy:
Expand All @@ -66,7 +51,9 @@ jobs:
ini-file: development
-
name: Update dependencies
run: composer update --no-progress --prefer-dist --no-interaction
run: |
composer remove --dev shipmonk/coverage-guard --no-update
composer update --no-progress --prefer-dist --no-interaction
-
name: Run dependency analyser
run: composer check:dependencies
Expand All @@ -89,7 +76,9 @@ jobs:
ini-file: development
-
name: Update dependencies
run: composer update --no-progress --prefer-dist --no-interaction
run: |
composer remove --dev shipmonk/coverage-guard --no-update
composer update --no-progress --prefer-dist --no-interaction
-
name: Run PHPStan
run: composer check:types
Expand All @@ -113,7 +102,9 @@ jobs:
ini-file: development
-
name: Update dependencies
run: composer update --no-progress --${{ matrix.dependency-version }} --prefer-dist --no-interaction ${{ matrix.php-version == '8.5' && '--ignore-platform-req=php+' || '' }}
run: |
composer remove --dev shipmonk/coverage-guard --no-update
composer update --no-progress --${{ matrix.dependency-version }} --prefer-dist --no-interaction
-
name: Run tests
run: vendor/bin/phpunit --no-coverage tests
7 changes: 6 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"phpunit/phpunit": "^9.6.22",
"shipmonk/coding-standard": "^0.2.0",
"shipmonk/composer-dependency-analyser": "^1.8.2",
"shipmonk/coverage-guard": "dev-master",
"shipmonk/name-collision-detector": "^2.1.1",
"shipmonk/phpstan-dev": "^0.1.1",
"shipmonk/phpstan-rules": "^4.1.0",
Expand Down Expand Up @@ -78,7 +79,7 @@
"@check:ec",
"@check:cs",
"@check:types",
"@check:tests",
"@check:coverage",
"@check:collisions",
"@check:dependencies"
],
Expand All @@ -87,6 +88,10 @@
"composer normalize --dry-run --no-update-lock",
"composer validate --strict"
],
"check:coverage": [
"XDEBUG_MODE=coverage phpunit tests --coverage-clover cache/clover.xml",
"coverage-guard check cache/clover.xml"
],
"check:cs": "phpcs",
"check:dependencies": "composer-dependency-analyser",
"check:ec": "ec src tests",
Expand Down
67 changes: 65 additions & 2 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

65 changes: 65 additions & 0 deletions coverage-guard.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

use PHPStan\Collectors\Collector;
use PHPStan\Rules\Rule;
use ShipMonk\CoverageGuard\Config;
use ShipMonk\CoverageGuard\Hierarchy\ClassMethodBlock;
use ShipMonk\CoverageGuard\Hierarchy\CodeBlock;
use ShipMonk\CoverageGuard\Rule\CoverageError;
use ShipMonk\CoverageGuard\Rule\CoverageRule;
use ShipMonk\CoverageGuard\Rule\InspectionContext;
use ShipMonk\PHPStan\DeadCode\Compatibility\BackwardCompatibilityChecker;
use ShipMonk\PHPStan\DeadCode\Provider\MemberUsageProvider;
use ShipMonk\PHPStan\DeadCode\Reflection\ReflectionHelper;

$config = new Config();
$config->addRule(new class implements CoverageRule {

public function inspect(
CodeBlock $codeBlock,
InspectionContext $context
): ?CoverageError
{
if (!$codeBlock instanceof ClassMethodBlock) {
return null;
}

if ($codeBlock->getExecutableLinesCount() < 5) {
return null;
}

$coverage = $codeBlock->getCoveragePercentage();
$classReflection = $codeBlock->getMethodReflection()->getDeclaringClass();
$requiredCoverage = $this->getRequiredCoverage($classReflection);

if ($codeBlock->getCoveragePercentage() < $requiredCoverage) {
return CoverageError::create("Method <white>{$codeBlock->getMethodName()}</white> requires $requiredCoverage% coverage, but has only $coverage%.");
}

return null;
}

/**
* @param ReflectionClass<object> $classReflection
*/
private function getRequiredCoverage(ReflectionClass $classReflection): int
{
$isPoor = in_array($classReflection->getName(), [
BackwardCompatibilityChecker::class,
ReflectionHelper::class,
], true);

$isCore = $classReflection->implementsInterface(MemberUsageProvider::class)
|| $classReflection->implementsInterface(Collector::class)
|| $classReflection->implementsInterface(Rule::class);

return match (true) {
$isCore => 80,
$isPoor => 20,
default => 50,
};
}

});

return $config;
7 changes: 0 additions & 7 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,6 @@
<include>
<directory suffix=".php">src</directory>
</include>
<report>
<clover outputFile="cache/coverage/phpstorm/clover.xml"/>
<cobertura outputFile="cache/coverage/ci/cobertura.xml"/>
<html outputDirectory="cache/coverage/html"/>
<text outputFile="cache/coverage/coverage.txt"/>
<php outputFile="cache/coverage/coverage.cov"/>
</report>
</coverage>
<php>
<ini name="error_reporting" value="-1"/>
Expand Down
2 changes: 2 additions & 0 deletions tests/Rule/data/providers/custom.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ class Methods
const SOME_CONSTANT = 1; // error: Unused CustomProvider\Methods::SOME_CONSTANT

public function method(): void {}

public function mixedTestThatExcludersCanExcludeProvidedUsage(): void {} // error: Unused CustomProvider\Methods::mixedTestThatExcludersCanExcludeProvidedUsage (all usages excluded by mixedPrefix excluder)
}

class Constants
Expand Down
5 changes: 5 additions & 0 deletions tests/Rule/data/providers/phpbench.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ public function benchWithParams(array $params): void
{
}

#[ParamProviders([1])]
public function benchWithInvalidAttributeDontBreakIt(array $params): void
{
}

public function provideParams(): array
{
return [];
Expand Down