Skip to content

Commit b4b45c2

Browse files
committed
Merge remote-tracking branch 'origin/2.1.x' into 2.2.x
2 parents a5cdfe9 + 4e70fc6 commit b4b45c2

62 files changed

Lines changed: 1690 additions & 387 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/bench.yml

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
name: "Benchmark"
2+
3+
on:
4+
pull_request:
5+
paths-ignore:
6+
- 'compiler/**'
7+
- 'apigen/**'
8+
- 'changelog-generator/**'
9+
- 'issue-bot/**'
10+
push:
11+
branches:
12+
- "2.1.x"
13+
paths-ignore:
14+
- 'compiler/**'
15+
- 'apigen/**'
16+
- 'changelog-generator/**'
17+
- 'issue-bot/**'
18+
19+
concurrency:
20+
group: bench-${{ github.head_ref || github.run_id }}
21+
cancel-in-progress: true
22+
23+
permissions:
24+
contents: read
25+
26+
jobs:
27+
baseline:
28+
name: "Baseline"
29+
runs-on: ubuntu-latest
30+
timeout-minutes: 60
31+
32+
steps:
33+
- name: Harden the runner (Audit all outbound calls)
34+
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
35+
with:
36+
egress-policy: audit
37+
38+
- name: "Checkout base branch"
39+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
40+
41+
- name: "Install PHP"
42+
uses: "shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1" # v2
43+
with:
44+
coverage: "none"
45+
php-version: "8.5"
46+
tools: pecl
47+
extensions: ds,mbstring
48+
ini-file: development
49+
ini-values: memory_limit=-1
50+
51+
- uses: "ramsey/composer-install@3cf229dc2919194e9e36783941438d17239e8520" # v3
52+
- uses: "ramsey/composer-install@3cf229dc2919194e9e36783941438d17239e8520" # v3
53+
with:
54+
working-directory: "tests/"
55+
56+
- name: "Run phpbench baseline"
57+
run: "tests/vendor/bin/phpbench run --dump-file=tests/bench/storage/baseline.xml"
58+
59+
- name: "Upload baseline artifact"
60+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
61+
with:
62+
name: phpbench-baseline
63+
path: tests/bench/storage/baseline.xml
64+
65+
test:
66+
name: "Test"
67+
runs-on: ubuntu-latest
68+
timeout-minutes: 60
69+
70+
steps:
71+
- name: Harden the runner (Audit all outbound calls)
72+
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
73+
with:
74+
egress-policy: audit
75+
76+
- name: "Checkout"
77+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
78+
79+
- name: "Install PHP"
80+
uses: "shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1" # v2
81+
with:
82+
coverage: "none"
83+
php-version: "8.5"
84+
tools: pecl
85+
extensions: ds,mbstring
86+
ini-file: development
87+
ini-values: memory_limit=-1
88+
89+
- uses: "ramsey/composer-install@3cf229dc2919194e9e36783941438d17239e8520" # v3
90+
- uses: "ramsey/composer-install@3cf229dc2919194e9e36783941438d17239e8520" # v3
91+
with:
92+
working-directory: "tests/"
93+
94+
- name: "Run phpbench test"
95+
run: "tests/vendor/bin/phpbench run --file=tests/bench/storage/baseline.xml --report=aggregate"

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ jobs:
259259

260260
- name: "Downgrade PHPUnit with Paratest"
261261
shell: bash
262-
run: "composer require --dev phpunit/phpunit:^9.6 brianium/paratest:^6.5 symfony/console:^5.4 symfony/process:^5.4 doctrine/instantiator:^1.0 --update-with-dependencies --ignore-platform-reqs --working-dir=tests"
262+
run: "composer require --dev phpbench/phpbench:^1.2.15 phpunit/phpunit:^9.6 brianium/paratest:^6.5 symfony/console:^5.4 symfony/process:^5.4 doctrine/instantiator:^1.0 --update-with-dependencies --ignore-platform-reqs --working-dir=tests"
263263

264264
- uses: ./.github/actions/downgrade-code
265265
with:

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@
1313
/tests/PHPStan/Reflection/data/golden/
1414
tmp/.memory_limit
1515
e2e/bashunit
16+
/.phpbench

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ tests-golden-reflection:
1414
lint:
1515
XDEBUG_MODE=off php vendor/bin/parallel-lint --colors \
1616
--exclude tests/PHPStan/Analyser/data \
17+
--exclude tests/bench/data \
18+
--exclude tests/bench/RegressionBench.php \
1719
--exclude tests/PHPStan/Analyser/nsrt \
1820
--exclude tests/PHPStan/Rules/Methods/data \
1921
--exclude tests/PHPStan/Rules/Functions/data \

build/phpstan.neon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ parameters:
3131
- ../tests/PHPStan/Analyser/nsrt/*
3232
- ../tests/PHPStan/Analyser/traits/*
3333
- ../tests/notAutoloaded/*
34+
- ../tests/bench/*
3435
- ../tests/PHPStan/Reflection/UnionTypesTest.php
3536
- ../tests/PHPStan/Reflection/MixedTypeTest.php
3637
- ../tests/e2e/magic-setter/*

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@
153153
},
154154
"classmap": [
155155
"tests/e2e",
156-
"tests/PHPStan"
156+
"tests/PHPStan",
157+
"tests/bench"
157158
]
158159
},
159160
"repositories": [

phpbench.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"$schema":"./tests/vendor/phpbench/phpbench/phpbench.schema.json",
3+
"runner.bootstrap": "vendor/autoload.php",
4+
"runner.path": "tests/bench",
5+
"runner.file_pattern": "*Bench.php",
6+
"storage.xml_storage_path": "tests/bench/storage"
7+
}

phpcs.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
</rule>
5454
<rule ref="SlevomatCodingStandard.Functions.UnusedInheritedVariablePassedToClosure.UnusedInheritedVariable">
5555
<exclude-pattern>src/Command/CommandHelper.php</exclude-pattern>
56-
<exclude-pattern>src/Testing/PHPStanTestCase.php</exclude-pattern>
56+
<exclude-pattern>src/Testing/PHPStanTestCaseTrait.php</exclude-pattern>
5757
</rule>
5858
<rule ref="SlevomatCodingStandard.Exceptions.ReferenceThrowableOnly.ReferencedGeneralException">
5959
<exclude-pattern>tests</exclude-pattern>
@@ -65,6 +65,7 @@
6565
<element key="compiler/tests" value="PHPStan\Compiler"/>
6666
<element key="src" value="PHPStan"/>
6767
<element key="tests/PHPStan" value="PHPStan"/>
68+
<element key="tests/bench" value="PHPStan\Benchmark"/>
6869
<element key="tests/e2e" value="PHPStan\Tests"/>
6970
<element key="apigen/src" value="PHPStan\ApiGen"/>
7071
<element key="changelog-generator/src" value="PHPStan\ChangelogGenerator"/>

src/Testing/PHPStanTestCase.php

Lines changed: 1 addition & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,9 @@
88
use PHPStan\Analyser\ScopeFactory;
99
use PHPStan\Analyser\TypeSpecifier;
1010
use PHPStan\BetterReflection\Reflector\Reflector;
11-
use PHPStan\DependencyInjection\Container;
12-
use PHPStan\DependencyInjection\ContainerFactory;
1311
use PHPStan\DependencyInjection\Reflection\ClassReflectionExtensionRegistryProvider;
1412
use PHPStan\DependencyInjection\Type\ExpressionTypeResolverExtensionRegistryProvider;
1513
use PHPStan\DependencyInjection\Type\OperatorTypeSpecifyingExtensionRegistryProvider;
16-
use PHPStan\File\FileHelper;
17-
use PHPStan\Internal\DirectoryCreator;
18-
use PHPStan\Internal\DirectoryCreatorException;
1914
use PHPStan\Node\Printer\ExprPrinter;
2015
use PHPStan\Parser\Parser;
2116
use PHPStan\Php\ComposerPhpVersionFactory;
@@ -32,76 +27,17 @@
3227
use PHPStan\Type\UsefulTypeAliasResolver;
3328
use PHPUnit\Framework\ExpectationFailedException;
3429
use PHPUnit\Framework\TestCase;
35-
use function array_merge;
3630
use function count;
37-
use function hash;
3831
use function implode;
3932
use function rtrim;
4033
use function sprintf;
41-
use function sys_get_temp_dir;
4234
use const DIRECTORY_SEPARATOR;
43-
use const PHP_VERSION_ID;
4435

4536
/** @api */
4637
abstract class PHPStanTestCase extends TestCase
4738
{
4839

49-
/** @var array<string, Container> */
50-
private static array $containers = [];
51-
52-
/** @api */
53-
public static function getContainer(): Container
54-
{
55-
$additionalConfigFiles = [__DIR__ . '/TestCase.neon'];
56-
foreach (static::getAdditionalConfigFiles() as $configFile) {
57-
$additionalConfigFiles[] = $configFile;
58-
}
59-
$cacheKey = hash('sha256', implode("\n", $additionalConfigFiles));
60-
61-
if (!isset(self::$containers[$cacheKey])) {
62-
$tmpDir = sys_get_temp_dir() . '/phpstan-tests';
63-
try {
64-
DirectoryCreator::ensureDirectoryExists($tmpDir, 0777);
65-
} catch (DirectoryCreatorException $e) {
66-
self::fail($e->getMessage());
67-
}
68-
69-
$rootDir = __DIR__ . '/../..';
70-
$fileHelper = new FileHelper($rootDir);
71-
$rootDir = $fileHelper->normalizePath($rootDir, '/');
72-
$containerFactory = new ContainerFactory($rootDir);
73-
$container = $containerFactory->create($tmpDir, array_merge([
74-
$containerFactory->getConfigDirectory() . '/config.level8.neon',
75-
], $additionalConfigFiles), []);
76-
self::$containers[$cacheKey] = $container;
77-
78-
foreach ($container->getParameter('bootstrapFiles') as $bootstrapFile) {
79-
(static function (string $file) use ($container): void {
80-
require_once $file;
81-
})($bootstrapFile);
82-
}
83-
84-
if (PHP_VERSION_ID >= 80000) {
85-
require_once __DIR__ . '/../../stubs/runtime/Enum/UnitEnum.php';
86-
require_once __DIR__ . '/../../stubs/runtime/Enum/BackedEnum.php';
87-
require_once __DIR__ . '/../../stubs/runtime/Enum/ReflectionEnum.php';
88-
require_once __DIR__ . '/../../stubs/runtime/Enum/ReflectionEnumUnitCase.php';
89-
require_once __DIR__ . '/../../stubs/runtime/Enum/ReflectionEnumBackedCase.php';
90-
}
91-
} else {
92-
ContainerFactory::postInitializeContainer(self::$containers[$cacheKey]);
93-
}
94-
95-
return self::$containers[$cacheKey];
96-
}
97-
98-
/**
99-
* @return string[]
100-
*/
101-
public static function getAdditionalConfigFiles(): array
102-
{
103-
return [];
104-
}
40+
use PHPStanTestCaseTrait;
10541

10642
public static function getParser(): Parser
10743
{
@@ -188,11 +124,6 @@ protected function shouldTreatPhpDocTypesAsCertain(): bool
188124
return true;
189125
}
190126

191-
public static function getFileHelper(): FileHelper
192-
{
193-
return self::getContainer()->getByType(FileHelper::class);
194-
}
195-
196127
/**
197128
* Provides a DIRECTORY_SEPARATOR agnostic assertion helper, to compare file paths.
198129
*
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Testing;
4+
5+
use PHPStan\DependencyInjection\Container;
6+
use PHPStan\DependencyInjection\ContainerFactory;
7+
use PHPStan\File\FileHelper;
8+
use PHPStan\Internal\DirectoryCreator;
9+
use PHPStan\Internal\DirectoryCreatorException;
10+
use RuntimeException;
11+
use function array_merge;
12+
use function hash;
13+
use function implode;
14+
use function sys_get_temp_dir;
15+
use const PHP_VERSION_ID;
16+
17+
trait PHPStanTestCaseTrait
18+
{
19+
20+
/** @var array<string, Container> */
21+
private static array $containers = [];
22+
23+
public static function getContainer(): Container
24+
{
25+
$additionalConfigFiles = [__DIR__ . '/TestCase.neon'];
26+
foreach (static::getAdditionalConfigFiles() as $configFile) {
27+
$additionalConfigFiles[] = $configFile;
28+
}
29+
$cacheKey = hash('sha256', implode("\n", $additionalConfigFiles));
30+
31+
if (!isset(self::$containers[$cacheKey])) {
32+
$tmpDir = sys_get_temp_dir() . '/phpstan-tests';
33+
try {
34+
DirectoryCreator::ensureDirectoryExists($tmpDir, 0777);
35+
} catch (DirectoryCreatorException $e) {
36+
throw new RuntimeException($e->getMessage(), previous: $e);
37+
}
38+
39+
$rootDir = __DIR__ . '/../..';
40+
$fileHelper = new FileHelper($rootDir);
41+
$rootDir = $fileHelper->normalizePath($rootDir, '/');
42+
$containerFactory = new ContainerFactory($rootDir);
43+
$container = $containerFactory->create($tmpDir, array_merge([
44+
$containerFactory->getConfigDirectory() . '/config.level8.neon',
45+
], $additionalConfigFiles), []);
46+
self::$containers[$cacheKey] = $container;
47+
48+
foreach ($container->getParameter('bootstrapFiles') as $bootstrapFile) {
49+
(static function (string $file) use ($container): void {
50+
require_once $file;
51+
})($bootstrapFile);
52+
}
53+
54+
if (PHP_VERSION_ID >= 80000) {
55+
require_once __DIR__ . '/../../stubs/runtime/Enum/UnitEnum.php';
56+
require_once __DIR__ . '/../../stubs/runtime/Enum/BackedEnum.php';
57+
require_once __DIR__ . '/../../stubs/runtime/Enum/ReflectionEnum.php';
58+
require_once __DIR__ . '/../../stubs/runtime/Enum/ReflectionEnumUnitCase.php';
59+
require_once __DIR__ . '/../../stubs/runtime/Enum/ReflectionEnumBackedCase.php';
60+
}
61+
} else {
62+
ContainerFactory::postInitializeContainer(self::$containers[$cacheKey]);
63+
}
64+
65+
return self::$containers[$cacheKey];
66+
}
67+
68+
/**
69+
* @return string[]
70+
*/
71+
public static function getAdditionalConfigFiles(): array
72+
{
73+
return [];
74+
}
75+
76+
public static function getFileHelper(): FileHelper
77+
{
78+
return self::getContainer()->getByType(FileHelper::class);
79+
}
80+
81+
}

0 commit comments

Comments
 (0)