Skip to content
Merged
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
59 changes: 59 additions & 0 deletions .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# https://help.github.com/en/categories/automating-your-workflow-with-github-actions

name: "E2E Tests"

on:
pull_request:
push:
branches:
- "2.0.x"

concurrency:
group: e2e-${{ github.head_ref || github.run_id }} # will be canceled on subsequent pushes in pull requests but not branches
cancel-in-progress: true

permissions:
contents: read

jobs:
e2e-tests:
name: "E2E tests"
runs-on: "ubuntu-latest"
timeout-minutes: 60

strategy:
fail-fast: false
matrix:
include:
- script: |
cd e2e/composer-version
composer install
OUTPUT=$(../bashunit -a exit_code "1" "vendor/bin/phpstan analyze test.php --error-format=raw")
echo "$OUTPUT"
../bashunit -a contains 'test.php:12:Version requirement will always evaluate to false.' "$OUTPUT"
../bashunit -a contains 'test.php:32:Version requirement will always evaluate to false.' "$OUTPUT"

steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit

Check warning

Code scanning / zizmor

credential persistence through GitHub Actions artifacts Warning

credential persistence through GitHub Actions artifacts

- name: "Checkout"
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
Comment on lines +42 to +43

- name: "Install PHP"
uses: "shivammathur/setup-php@7c071dfe9dc99bdf297fa79cb49ea005b9fcadbc" # v2.37.1

Check notice

Code scanning / poutine

Github Action from Unverified Creator used Note

Usage of the following GitHub Actions repositories was detected in workflows
or composite actions, but their owner is not a verified creator.
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
with:
coverage: "none"
php-version: "8.3"

- uses: "ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda" # v4.0.0

Check notice

Code scanning / poutine

Github Action from Unverified Creator used Note

Usage of the following GitHub Actions repositories was detected in workflows
or composite actions, but their owner is not a verified creator.
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed

- name: "Install bashunit"
uses: "TypedDevs/bashunit@ffa9c79e71ecbb9990e777348bc9ba12314b62d0" # 0.39.1

Check notice

Code scanning / poutine

Github Action from Unverified Creator used Note

Usage of the following GitHub Actions repositories was detected in workflows
or composite actions, but their owner is not a verified creator.
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
with:
directory: "e2e"

Check warning

Code scanning / zizmor

code injection via template expansion Warning

code injection via template expansion

- name: "Test"
run: ${{ matrix.script }}
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"require": {
"php": "^7.4 || ^8.0",
"phar-io/version": "^3.2",
"phpstan/phpstan": "^2.2.3"
"phpstan/phpstan": "^2.2.6"
},
"conflict": {
"phpunit/phpunit": "<7.0"
Expand Down
2 changes: 2 additions & 0 deletions e2e/composer-version/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/vendor
composer.lock
20 changes: 20 additions & 0 deletions e2e/composer-version/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"require": {
"php": "^8.1",
"phpstan/phpstan": "@dev",
"phpstan/phpstan-phpunit": "@dev",
"phpunit/phpunit": "^12.5",
"phpstan/extension-installer": "^1.4"
},
"repositories": [
{
"type": "path",
"url": "../../"
}
],
"config": {
"allow-plugins": {
"phpstan/extension-installer": true
}
}
}
5 changes: 5 additions & 0 deletions e2e/composer-version/phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
includes:
- phar://phpstan.phar/conf/bleedingEdge.neon

parameters:
level: 5
34 changes: 34 additions & 0 deletions e2e/composer-version/test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

use PHPUnit\Framework\Attributes\RequiresPhp;
use PHPUnit\Framework\Attributes\RequiresPhpunit;

class A extends \PHPUnit\Framework\TestCase {
#[RequiresPhp('<=8.2.0')]
public function testFoo() {}
}

class B extends \PHPUnit\Framework\TestCase {
#[RequiresPhp('<=8.0.0')]
public function testFoo() {}
}

class C extends \PHPUnit\Framework\TestCase {
#[RequiresPhp('^8.0.0')]
public function testFoo() {}
}

class D extends \PHPUnit\Framework\TestCase {
#[RequiresPhp('^8.1.0')]
public function testFoo() {}
}

class E extends \PHPUnit\Framework\TestCase {
#[RequiresPhpunit('^12.0.0')]
public function testFoo() {}
}

class F extends \PHPUnit\Framework\TestCase {
#[RequiresPhpunit('^11.0.0')]
public function testFoo() {}
}
39 changes: 13 additions & 26 deletions src/Rules/PHPUnit/AttributeVersionRequirementHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@
use PharIo\Version\VersionConstraintParser;
use PHPStan\Analyser\Scope;
use PHPStan\BetterReflection\Reflection\ReflectionAttribute;
use PHPStan\Php\ConfiguredPhpVersionRangeHelper;
use PHPStan\Php\PhpMinorVersionIterator;
use PHPStan\Php\PhpVersion;
use PHPStan\Rules\IdentifierRuleError;
use PHPStan\Rules\RuleErrorBuilder;
use PHPStan\Type\Constant\ConstantIntegerType;
use PHPStan\Type\IntegerRangeType;
use function count;
use function is_numeric;
use function preg_match;
Expand All @@ -28,8 +26,6 @@ final class AttributeVersionRequirementHelper

private PHPUnitVersion $PHPUnitVersion;

private PhpVersion $fallbackPhpVersion;

/**
* When phpstan-deprecation-rules is installed, rule reports deprecated usages.
*/
Expand All @@ -42,19 +38,21 @@ final class AttributeVersionRequirementHelper

private bool $bleedingEdge;

private ConfiguredPhpVersionRangeHelper $phpVersionRangeHelper;

public function __construct(
PHPUnitVersion $PHPUnitVersion,
PhpVersion $phpVersion,
ConfiguredPhpVersionRangeHelper $phpVersionRangeHelper,
bool $deprecationRulesInstalled = false,
bool $bleedingEdge = false,
bool $warnAboutIncompleteVersion = true
)
{
$this->PHPUnitVersion = $PHPUnitVersion;
$this->deprecationRulesInstalled = $deprecationRulesInstalled;
$this->fallbackPhpVersion = $phpVersion;
$this->warnAboutIncompleteVersion = $warnAboutIncompleteVersion;
$this->bleedingEdge = $bleedingEdge;
$this->phpVersionRangeHelper = $phpVersionRangeHelper;
}

/**
Expand All @@ -64,11 +62,6 @@ public function __construct(
*/
public function checkVersionRequirement(array $attributes, Scope $scope): array
{
$phpstanPharIoVersions = $this->getAnalyzedPhpVersions($scope);
if ($phpstanPharIoVersions === []) {
return [];
}

$errors = [];
$parser = new VersionConstraintParser();
foreach ($attributes as $attr) {
Expand Down Expand Up @@ -99,7 +92,7 @@ public function checkVersionRequirement(array $attributes, Scope $scope): array

$pharIoVersions = strpos($attr->getName(), 'RequiresPhpunit') !== false
? $this->PHPUnitVersion->getPharIoVersions()
: $phpstanPharIoVersions;
: $this->getAnalyzedPhpVersions();
if ($pharIoVersions === []) {
continue;
}
Expand Down Expand Up @@ -168,29 +161,23 @@ public function checkVersionRequirement(array $attributes, Scope $scope): array
/**
* @return Version[]
*/
private function getAnalyzedPhpVersions(Scope $scope): array
private function getAnalyzedPhpVersions(): array
{
$scopePhpVersion = $scope->getPhpVersion()->getType();
if ($scopePhpVersion instanceof ConstantIntegerType) {
$v = new PhpVersion($scopePhpVersion->getValue());
return [new Version($v->getVersionString())];
} elseif ($scopePhpVersion instanceof IntegerRangeType) {
if ($scopePhpVersion->getMin() === null || $scopePhpVersion->getMax() === null) {
return [];
}

// @phpstan-ignore phpstanApi.method

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was not sure, whether we would want to have a @api on ConfiguredPhpVersionRangeHelper.

thats why I used the ignores for now

[$minVersion, $maxVersion] = $this->phpVersionRangeHelper->getVersionRange();
if ($minVersion !== null && $maxVersion !== null) {
$versions = [];
$minorVersionIterator = new PhpMinorVersionIterator(
new PhpVersion($scopePhpVersion->getMin()),
new PhpVersion($scopePhpVersion->getMax()),
$minVersion,
$maxVersion,
);
foreach ($minorVersionIterator as $phpstanVersion) {
$versions[] = new Version($phpstanVersion->getVersionString());
}
return $versions;
}

return [new Version($this->fallbackPhpVersion->getVersionString())];
return [];
}

// see https://github.com/sebastianbergmann/phpunit/issues/6451
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace PHPStan\Rules\PHPUnit;

use PHPStan\Php\PhpVersion;
use PHPStan\Php\ConfiguredPhpVersionRangeHelper;
use PHPStan\Rules\Rule;
use PHPStan\Testing\RuleTestCase;
use PHPStan\Type\FileTypeMapper;
Expand All @@ -13,8 +13,6 @@
final class AttributeRequiresPhpVersionRangeRuleTest extends RuleTestCase
{

private int $phpVersion = 80500;

public function testPhpVersionMismatch(): void
{
$this->analyse([__DIR__ . '/data/requires-php-version-mismatch.php'], [
Expand Down Expand Up @@ -52,7 +50,7 @@ protected function getRule(): Rule
),
new AttributeVersionRequirementHelper(
$phpunitVersion,
new PhpVersion($this->phpVersion),
self::getContainer()->getByType(ConfiguredPhpVersionRangeHelper::class), // @phpstan-ignore phpstanApi.classConstant
false,
true,
),
Expand Down
4 changes: 3 additions & 1 deletion tests/Rules/PHPUnit/AttributeRequiresPhpVersionRule.neon
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
parameters:
phpVersion: 80500
phpVersion:
min: 80500
max: 80599
Comment on lines +2 to +4

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adjusted to replicate the behaviour the tests expected before this PR

6 changes: 2 additions & 4 deletions tests/Rules/PHPUnit/AttributeRequiresPhpVersionRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace PHPStan\Rules\PHPUnit;

use PHPStan\Php\PhpVersion;
use PHPStan\Php\ConfiguredPhpVersionRangeHelper;
use PHPStan\Rules\Rule;
use PHPStan\Testing\RuleTestCase;
use PHPStan\Type\FileTypeMapper;
Expand All @@ -13,8 +13,6 @@
final class AttributeRequiresPhpVersionRuleTest extends RuleTestCase
{

private int $phpVersion = 80500;

private ?int $phpunitMajorVersion;

private ?int $phpunitMinorVersion;
Expand Down Expand Up @@ -196,7 +194,7 @@ protected function getRule(): Rule
),
new AttributeVersionRequirementHelper(
$phpunitVersion,
new PhpVersion($this->phpVersion),
self::getContainer()->getByType(ConfiguredPhpVersionRangeHelper::class), // @phpstan-ignore phpstanApi.classConstant
$this->deprecationRulesInstalled,
true,
$this->warnAboutIncompleteVersion,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
parameters:
phpVersion: 80210
Comment on lines +1 to +2

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test is asserting new behaviour.

before this PR we errored on such single-version configs.
after this PR we skip them.

46 changes: 46 additions & 0 deletions tests/Rules/PHPUnit/AttributeRequiresSinglePhpVersionRuleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php declare(strict_types = 1);

namespace PHPStan\Rules\PHPUnit;

use PHPStan\Php\ConfiguredPhpVersionRangeHelper;
use PHPStan\Rules\Rule;
use PHPStan\Testing\RuleTestCase;
use PHPStan\Type\FileTypeMapper;

/**
* @extends RuleTestCase<AttributeRequiresPhpVersionRule>
*/
final class AttributeRequiresSinglePhpVersionRuleTest extends RuleTestCase
{

public function testPhpVersionMismatch(): void
{
$this->analyse([__DIR__ . '/data/requires-php-version-mismatch.php'], []);
}

protected function getRule(): Rule
{
$phpunitVersion = new PHPUnitVersion(null, null);

return new AttributeRequiresPhpVersionRule(
new TestMethodsHelper(
self::getContainer()->getByType(FileTypeMapper::class),
$phpunitVersion,
),
new AttributeVersionRequirementHelper(
$phpunitVersion,
self::getContainer()->getByType(ConfiguredPhpVersionRangeHelper::class), // @phpstan-ignore phpstanApi.classConstant
false,
true,
),
);
}

public static function getAdditionalConfigFiles(): array
{
return [
__DIR__ . '/AttributeRequiresSinglePhpVersionRule.neon',
];
}

}
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
parameters:
phpVersion: 80500
phpVersion:
min: 80500
max: 80599
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace PHPStan\Rules\PHPUnit;

use PHPStan\Php\PhpVersion;
use PHPStan\Php\ConfiguredPhpVersionRangeHelper;
use PHPStan\Rules\Rule;
use PHPStan\Testing\RuleTestCase;

Expand All @@ -12,8 +12,6 @@
final class ClassAttributeRequiresPhpVersionRuleTest extends RuleTestCase
{

private int $phpVersion = 80500;

private int $phpunitMajorVersion;

private int $phpunitMinorVersion;
Expand Down Expand Up @@ -59,7 +57,7 @@ protected function getRule(): Rule
return new ClassAttributeRequiresPhpVersionRule(
new AttributeVersionRequirementHelper(
$phpunitVersion,
new PhpVersion($this->phpVersion),
self::getContainer()->getByType(ConfiguredPhpVersionRangeHelper::class), // @phpstan-ignore phpstanApi.classConstant
false,
true,
$this->warnAboutIncompleteVersion,
Expand Down
Loading