mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-13 06:32:22 +00:00
Updated Rector to commit d9374ddfa6c8a1ae41c1ac271d102980c6eba8f5
d9374ddfa6
[Dep] Move phpstan-phpunit to require-dev (#3734)
This commit is contained in:
parent
1e2a0a6217
commit
61359ad57c
|
@ -19,12 +19,12 @@ final class VersionResolver
|
|||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const PACKAGE_VERSION = '8b48059c347d98d191478504da236c4c2ba1e667';
|
||||
public const PACKAGE_VERSION = 'd9374ddfa6c8a1ae41c1ac271d102980c6eba8f5';
|
||||
/**
|
||||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const RELEASE_DATE = '2023-05-05 09:12:04';
|
||||
public const RELEASE_DATE = '2023-05-05 16:30:49';
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
|
|
2
vendor/autoload.php
vendored
2
vendor/autoload.php
vendored
|
@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) {
|
|||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInita3d85d0220e4ded852f7ff0a91ee1f48::getLoader();
|
||||
return ComposerAutoloaderInitdef1a712419aaa37ea20f1fb4d4e81bb::getLoader();
|
||||
|
|
23
vendor/composer/autoload_classmap.php
vendored
23
vendor/composer/autoload_classmap.php
vendored
|
@ -80,29 +80,6 @@ return array(
|
|||
'PHPStan\\PhpDocParser\\Parser\\StringUnescaper' => $vendorDir . '/phpstan/phpdoc-parser/src/Parser/StringUnescaper.php',
|
||||
'PHPStan\\PhpDocParser\\Parser\\TokenIterator' => $vendorDir . '/phpstan/phpdoc-parser/src/Parser/TokenIterator.php',
|
||||
'PHPStan\\PhpDocParser\\Parser\\TypeParser' => $vendorDir . '/phpstan/phpdoc-parser/src/Parser/TypeParser.php',
|
||||
'PHPStan\\PhpDoc\\PHPUnit\\MockObjectTypeNodeResolverExtension' => $vendorDir . '/phpstan/phpstan-phpunit/src/PhpDoc/PHPUnit/MockObjectTypeNodeResolverExtension.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\AnnotationHelper' => $vendorDir . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/AnnotationHelper.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\AssertRuleHelper' => $vendorDir . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/AssertRuleHelper.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\AssertSameBooleanExpectedRule' => $vendorDir . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/AssertSameBooleanExpectedRule.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\AssertSameNullExpectedRule' => $vendorDir . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/AssertSameNullExpectedRule.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\AssertSameWithCountRule' => $vendorDir . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/AssertSameWithCountRule.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\ClassCoversExistsRule' => $vendorDir . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/ClassCoversExistsRule.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\ClassMethodCoversExistsRule' => $vendorDir . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/ClassMethodCoversExistsRule.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\CoversHelper' => $vendorDir . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/CoversHelper.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\DataProviderDeclarationRule' => $vendorDir . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/DataProviderDeclarationRule.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\DataProviderHelper' => $vendorDir . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/DataProviderHelper.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\DataProviderHelperFactory' => $vendorDir . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/DataProviderHelperFactory.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\MockMethodCallRule' => $vendorDir . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/MockMethodCallRule.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\NoMissingSpaceInClassAnnotationRule' => $vendorDir . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/NoMissingSpaceInClassAnnotationRule.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\NoMissingSpaceInMethodAnnotationRule' => $vendorDir . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/NoMissingSpaceInMethodAnnotationRule.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\ShouldCallParentMethodsRule' => $vendorDir . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/ShouldCallParentMethodsRule.php',
|
||||
'PHPStan\\Type\\PHPUnit\\Assert\\AssertFunctionTypeSpecifyingExtension' => $vendorDir . '/phpstan/phpstan-phpunit/src/Type/PHPUnit/Assert/AssertFunctionTypeSpecifyingExtension.php',
|
||||
'PHPStan\\Type\\PHPUnit\\Assert\\AssertMethodTypeSpecifyingExtension' => $vendorDir . '/phpstan/phpstan-phpunit/src/Type/PHPUnit/Assert/AssertMethodTypeSpecifyingExtension.php',
|
||||
'PHPStan\\Type\\PHPUnit\\Assert\\AssertStaticMethodTypeSpecifyingExtension' => $vendorDir . '/phpstan/phpstan-phpunit/src/Type/PHPUnit/Assert/AssertStaticMethodTypeSpecifyingExtension.php',
|
||||
'PHPStan\\Type\\PHPUnit\\Assert\\AssertTypeSpecifyingExtensionHelper' => $vendorDir . '/phpstan/phpstan-phpunit/src/Type/PHPUnit/Assert/AssertTypeSpecifyingExtensionHelper.php',
|
||||
'PHPStan\\Type\\PHPUnit\\InvocationMockerDynamicReturnTypeExtension' => $vendorDir . '/phpstan/phpstan-phpunit/src/Type/PHPUnit/InvocationMockerDynamicReturnTypeExtension.php',
|
||||
'PHPStan\\Type\\PHPUnit\\MockBuilderDynamicReturnTypeExtension' => $vendorDir . '/phpstan/phpstan-phpunit/src/Type/PHPUnit/MockBuilderDynamicReturnTypeExtension.php',
|
||||
'PHPStan\\Type\\PHPUnit\\MockObjectDynamicReturnTypeExtension' => $vendorDir . '/phpstan/phpstan-phpunit/src/Type/PHPUnit/MockObjectDynamicReturnTypeExtension.php',
|
||||
'PhpParser\\Builder' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder.php',
|
||||
'PhpParser\\BuilderFactory' => $vendorDir . '/nikic/php-parser/lib/PhpParser/BuilderFactory.php',
|
||||
'PhpParser\\BuilderHelpers' => $vendorDir . '/nikic/php-parser/lib/PhpParser/BuilderHelpers.php',
|
||||
|
|
1
vendor/composer/autoload_psr4.php
vendored
1
vendor/composer/autoload_psr4.php
vendored
|
@ -48,5 +48,4 @@ return array(
|
|||
'RectorPrefix202305\\Clue\\React\\NDJson\\' => array($vendorDir . '/clue/ndjson-react/src'),
|
||||
'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'),
|
||||
'PHPStan\\PhpDocParser\\' => array($vendorDir . '/phpstan/phpdoc-parser/src'),
|
||||
'PHPStan\\' => array($vendorDir . '/phpstan/phpstan-phpunit/src'),
|
||||
);
|
||||
|
|
10
vendor/composer/autoload_real.php
vendored
10
vendor/composer/autoload_real.php
vendored
|
@ -2,7 +2,7 @@
|
|||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInita3d85d0220e4ded852f7ff0a91ee1f48
|
||||
class ComposerAutoloaderInitdef1a712419aaa37ea20f1fb4d4e81bb
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
|
@ -22,17 +22,17 @@ class ComposerAutoloaderInita3d85d0220e4ded852f7ff0a91ee1f48
|
|||
return self::$loader;
|
||||
}
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInita3d85d0220e4ded852f7ff0a91ee1f48', 'loadClassLoader'), true, true);
|
||||
spl_autoload_register(array('ComposerAutoloaderInitdef1a712419aaa37ea20f1fb4d4e81bb', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInita3d85d0220e4ded852f7ff0a91ee1f48', 'loadClassLoader'));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInitdef1a712419aaa37ea20f1fb4d4e81bb', 'loadClassLoader'));
|
||||
|
||||
require __DIR__ . '/autoload_static.php';
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInita3d85d0220e4ded852f7ff0a91ee1f48::getInitializer($loader));
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInitdef1a712419aaa37ea20f1fb4d4e81bb::getInitializer($loader));
|
||||
|
||||
$loader->setClassMapAuthoritative(true);
|
||||
$loader->register(true);
|
||||
|
||||
$filesToLoad = \Composer\Autoload\ComposerStaticInita3d85d0220e4ded852f7ff0a91ee1f48::$files;
|
||||
$filesToLoad = \Composer\Autoload\ComposerStaticInitdef1a712419aaa37ea20f1fb4d4e81bb::$files;
|
||||
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
|
|
36
vendor/composer/autoload_static.php
vendored
36
vendor/composer/autoload_static.php
vendored
|
@ -4,7 +4,7 @@
|
|||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInita3d85d0220e4ded852f7ff0a91ee1f48
|
||||
class ComposerStaticInitdef1a712419aaa37ea20f1fb4d4e81bb
|
||||
{
|
||||
public static $files = array (
|
||||
'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
|
||||
|
@ -70,7 +70,6 @@ class ComposerStaticInita3d85d0220e4ded852f7ff0a91ee1f48
|
|||
array (
|
||||
'PhpParser\\' => 10,
|
||||
'PHPStan\\PhpDocParser\\' => 21,
|
||||
'PHPStan\\' => 8,
|
||||
),
|
||||
);
|
||||
|
||||
|
@ -246,10 +245,6 @@ class ComposerStaticInita3d85d0220e4ded852f7ff0a91ee1f48
|
|||
array (
|
||||
0 => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src',
|
||||
),
|
||||
'PHPStan\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/phpstan/phpstan-phpunit/src',
|
||||
),
|
||||
);
|
||||
|
||||
public static $classMap = array (
|
||||
|
@ -327,29 +322,6 @@ class ComposerStaticInita3d85d0220e4ded852f7ff0a91ee1f48
|
|||
'PHPStan\\PhpDocParser\\Parser\\StringUnescaper' => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src/Parser/StringUnescaper.php',
|
||||
'PHPStan\\PhpDocParser\\Parser\\TokenIterator' => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src/Parser/TokenIterator.php',
|
||||
'PHPStan\\PhpDocParser\\Parser\\TypeParser' => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src/Parser/TypeParser.php',
|
||||
'PHPStan\\PhpDoc\\PHPUnit\\MockObjectTypeNodeResolverExtension' => __DIR__ . '/..' . '/phpstan/phpstan-phpunit/src/PhpDoc/PHPUnit/MockObjectTypeNodeResolverExtension.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\AnnotationHelper' => __DIR__ . '/..' . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/AnnotationHelper.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\AssertRuleHelper' => __DIR__ . '/..' . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/AssertRuleHelper.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\AssertSameBooleanExpectedRule' => __DIR__ . '/..' . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/AssertSameBooleanExpectedRule.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\AssertSameNullExpectedRule' => __DIR__ . '/..' . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/AssertSameNullExpectedRule.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\AssertSameWithCountRule' => __DIR__ . '/..' . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/AssertSameWithCountRule.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\ClassCoversExistsRule' => __DIR__ . '/..' . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/ClassCoversExistsRule.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\ClassMethodCoversExistsRule' => __DIR__ . '/..' . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/ClassMethodCoversExistsRule.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\CoversHelper' => __DIR__ . '/..' . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/CoversHelper.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\DataProviderDeclarationRule' => __DIR__ . '/..' . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/DataProviderDeclarationRule.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\DataProviderHelper' => __DIR__ . '/..' . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/DataProviderHelper.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\DataProviderHelperFactory' => __DIR__ . '/..' . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/DataProviderHelperFactory.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\MockMethodCallRule' => __DIR__ . '/..' . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/MockMethodCallRule.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\NoMissingSpaceInClassAnnotationRule' => __DIR__ . '/..' . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/NoMissingSpaceInClassAnnotationRule.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\NoMissingSpaceInMethodAnnotationRule' => __DIR__ . '/..' . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/NoMissingSpaceInMethodAnnotationRule.php',
|
||||
'PHPStan\\Rules\\PHPUnit\\ShouldCallParentMethodsRule' => __DIR__ . '/..' . '/phpstan/phpstan-phpunit/src/Rules/PHPUnit/ShouldCallParentMethodsRule.php',
|
||||
'PHPStan\\Type\\PHPUnit\\Assert\\AssertFunctionTypeSpecifyingExtension' => __DIR__ . '/..' . '/phpstan/phpstan-phpunit/src/Type/PHPUnit/Assert/AssertFunctionTypeSpecifyingExtension.php',
|
||||
'PHPStan\\Type\\PHPUnit\\Assert\\AssertMethodTypeSpecifyingExtension' => __DIR__ . '/..' . '/phpstan/phpstan-phpunit/src/Type/PHPUnit/Assert/AssertMethodTypeSpecifyingExtension.php',
|
||||
'PHPStan\\Type\\PHPUnit\\Assert\\AssertStaticMethodTypeSpecifyingExtension' => __DIR__ . '/..' . '/phpstan/phpstan-phpunit/src/Type/PHPUnit/Assert/AssertStaticMethodTypeSpecifyingExtension.php',
|
||||
'PHPStan\\Type\\PHPUnit\\Assert\\AssertTypeSpecifyingExtensionHelper' => __DIR__ . '/..' . '/phpstan/phpstan-phpunit/src/Type/PHPUnit/Assert/AssertTypeSpecifyingExtensionHelper.php',
|
||||
'PHPStan\\Type\\PHPUnit\\InvocationMockerDynamicReturnTypeExtension' => __DIR__ . '/..' . '/phpstan/phpstan-phpunit/src/Type/PHPUnit/InvocationMockerDynamicReturnTypeExtension.php',
|
||||
'PHPStan\\Type\\PHPUnit\\MockBuilderDynamicReturnTypeExtension' => __DIR__ . '/..' . '/phpstan/phpstan-phpunit/src/Type/PHPUnit/MockBuilderDynamicReturnTypeExtension.php',
|
||||
'PHPStan\\Type\\PHPUnit\\MockObjectDynamicReturnTypeExtension' => __DIR__ . '/..' . '/phpstan/phpstan-phpunit/src/Type/PHPUnit/MockObjectDynamicReturnTypeExtension.php',
|
||||
'PhpParser\\Builder' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder.php',
|
||||
'PhpParser\\BuilderFactory' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/BuilderFactory.php',
|
||||
'PhpParser\\BuilderHelpers' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/BuilderHelpers.php',
|
||||
|
@ -3152,9 +3124,9 @@ class ComposerStaticInita3d85d0220e4ded852f7ff0a91ee1f48
|
|||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInita3d85d0220e4ded852f7ff0a91ee1f48::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInita3d85d0220e4ded852f7ff0a91ee1f48::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInita3d85d0220e4ded852f7ff0a91ee1f48::$classMap;
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInitdef1a712419aaa37ea20f1fb4d4e81bb::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInitdef1a712419aaa37ea20f1fb4d4e81bb::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInitdef1a712419aaa37ea20f1fb4d4e81bb::$classMap;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
|
|
55
vendor/composer/installed.json
vendored
55
vendor/composer/installed.json
vendored
|
@ -932,61 +932,6 @@
|
|||
],
|
||||
"install-path": "..\/phpstan\/phpstan"
|
||||
},
|
||||
{
|
||||
"name": "phpstan\/phpstan-phpunit",
|
||||
"version": "1.3.11",
|
||||
"version_normalized": "1.3.11.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https:\/\/github.com\/phpstan\/phpstan-phpunit.git",
|
||||
"reference": "9e1b9de6d260461f6e99b6a8f2dbb0bbb98b579c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https:\/\/api.github.com\/repos\/phpstan\/phpstan-phpunit\/zipball\/9e1b9de6d260461f6e99b6a8f2dbb0bbb98b579c",
|
||||
"reference": "9e1b9de6d260461f6e99b6a8f2dbb0bbb98b579c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0",
|
||||
"phpstan\/phpstan": "^1.10"
|
||||
},
|
||||
"conflict": {
|
||||
"phpunit\/phpunit": "<7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"nikic\/php-parser": "^4.13.0",
|
||||
"php-parallel-lint\/php-parallel-lint": "^1.2",
|
||||
"phpstan\/phpstan-strict-rules": "^1.0",
|
||||
"phpunit\/phpunit": "^9.5"
|
||||
},
|
||||
"time": "2023-03-25T19:42:13+00:00",
|
||||
"type": "phpstan-extension",
|
||||
"extra": {
|
||||
"phpstan": {
|
||||
"includes": [
|
||||
"extension.neon",
|
||||
"rules.neon"
|
||||
]
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PHPStan\\": "src\/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https:\/\/packagist.org\/downloads\/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "PHPUnit extensions and rules for PHPStan",
|
||||
"support": {
|
||||
"issues": "https:\/\/github.com\/phpstan\/phpstan-phpunit\/issues",
|
||||
"source": "https:\/\/github.com\/phpstan\/phpstan-phpunit\/tree\/1.3.11"
|
||||
},
|
||||
"install-path": "..\/phpstan\/phpstan-phpunit"
|
||||
},
|
||||
{
|
||||
"name": "psr\/cache",
|
||||
"version": "3.0.0",
|
||||
|
|
2
vendor/composer/installed.php
vendored
2
vendor/composer/installed.php
vendored
File diff suppressed because one or more lines are too long
22
vendor/phpstan/phpstan-phpunit/LICENSE
vendored
22
vendor/phpstan/phpstan-phpunit/LICENSE
vendored
|
@ -1,22 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2016 Ondřej Mirtes
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
96
vendor/phpstan/phpstan-phpunit/README.md
vendored
96
vendor/phpstan/phpstan-phpunit/README.md
vendored
|
@ -1,96 +0,0 @@
|
|||
# PHPStan PHPUnit extensions and rules
|
||||
|
||||
[![Build](https://github.com/phpstan/phpstan-phpunit/workflows/Build/badge.svg)](https://github.com/phpstan/phpstan-phpunit/actions)
|
||||
[![Latest Stable Version](https://poser.pugx.org/phpstan/phpstan-phpunit/v/stable)](https://packagist.org/packages/phpstan/phpstan-phpunit)
|
||||
[![License](https://poser.pugx.org/phpstan/phpstan-phpunit/license)](https://packagist.org/packages/phpstan/phpstan-phpunit)
|
||||
|
||||
* [PHPStan](https://phpstan.org/)
|
||||
* [PHPUnit](https://phpunit.de)
|
||||
|
||||
This extension provides following features:
|
||||
|
||||
* `createMock()`, `getMockForAbstractClass()` and `getMockFromWsdl()` methods return an intersection type (see the [detailed explanation of intersection types](https://phpstan.org/blog/union-types-vs-intersection-types)) of the mock object and the mocked class so that both methods from the mock object (like `expects`) and from the mocked class are available on the object.
|
||||
* `getMock()` called on `MockBuilder` is also supported.
|
||||
* Interprets `Foo|PHPUnit_Framework_MockObject_MockObject` in phpDoc so that it results in an intersection type instead of a union type.
|
||||
* Defines early terminating method calls for the `PHPUnit\Framework\TestCase` class to prevent undefined variable errors.
|
||||
* Specifies types of expressions passed to various `assert` methods like `assertInstanceOf`, `assertTrue`, `assertInternalType` etc.
|
||||
* Combined with PHPStan's level 4, it points out always-true and always-false asserts like `assertTrue(true)` etc.
|
||||
|
||||
It also contains this strict framework-specific rules (can be enabled separately):
|
||||
|
||||
* Check that you are not using `assertSame()` with `true` as expected value. `assertTrue()` should be used instead.
|
||||
* Check that you are not using `assertSame()` with `false` as expected value. `assertFalse()` should be used instead.
|
||||
* Check that you are not using `assertSame()` with `null` as expected value. `assertNull()` should be used instead.
|
||||
* Check that you are not using `assertSame()` with `count($variable)` as second parameter. `assertCount($variable)` should be used instead.
|
||||
|
||||
## How to document mock objects in phpDocs?
|
||||
|
||||
If you need to configure the mock even after you assign it to a property or return it from a method, you should add `PHPUnit_Framework_MockObject_MockObject` to the phpDoc:
|
||||
|
||||
```php
|
||||
/**
|
||||
* @return Foo&PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
private function createFooMock()
|
||||
{
|
||||
return $this->createMock(Foo::class);
|
||||
}
|
||||
|
||||
public function testSomething()
|
||||
{
|
||||
$fooMock = $this->createFooMock();
|
||||
$fooMock->method('doFoo')->will($this->returnValue('test'));
|
||||
$fooMock->doFoo();
|
||||
}
|
||||
```
|
||||
|
||||
Please note that the correct syntax for intersection types is `Foo&PHPUnit_Framework_MockObject_MockObject`. `Foo|PHPUnit_Framework_MockObject_MockObject` is also supported, but only for ecosystem and legacy reasons.
|
||||
|
||||
If the mock is fully configured and only the methods of the mocked class are supposed to be called on the value, it's fine to typehint only the mocked class:
|
||||
|
||||
```php
|
||||
/** @var Foo */
|
||||
private $foo;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$fooMock = $this->createMock(Foo::class);
|
||||
$fooMock->method('doFoo')->will($this->returnValue('test'));
|
||||
$this->foo = $fooMock;
|
||||
}
|
||||
|
||||
public function testSomething()
|
||||
{
|
||||
$this->foo->doFoo();
|
||||
// $this->foo->method() and expects() can no longer be called
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
To use this extension, require it in [Composer](https://getcomposer.org/):
|
||||
|
||||
```
|
||||
composer require --dev phpstan/phpstan-phpunit
|
||||
```
|
||||
|
||||
If you also install [phpstan/extension-installer](https://github.com/phpstan/extension-installer) then you're all set!
|
||||
|
||||
<details>
|
||||
<summary>Manual installation</summary>
|
||||
|
||||
If you don't want to use `phpstan/extension-installer`, include extension.neon in your project's PHPStan config:
|
||||
|
||||
```
|
||||
includes:
|
||||
- vendor/phpstan/phpstan-phpunit/extension.neon
|
||||
```
|
||||
|
||||
To perform framework-specific checks, include also this file:
|
||||
|
||||
```
|
||||
- vendor/phpstan/phpstan-phpunit/rules.neon
|
||||
```
|
||||
|
||||
</details>
|
47
vendor/phpstan/phpstan-phpunit/composer.json
vendored
47
vendor/phpstan/phpstan-phpunit/composer.json
vendored
|
@ -1,47 +0,0 @@
|
|||
{
|
||||
"name": "phpstan\/phpstan-phpunit",
|
||||
"type": "phpstan-extension",
|
||||
"description": "PHPUnit extensions and rules for PHPStan",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0",
|
||||
"phpstan\/phpstan": "^1.10"
|
||||
},
|
||||
"conflict": {
|
||||
"phpunit\/phpunit": "<7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"nikic\/php-parser": "^4.13.0",
|
||||
"php-parallel-lint\/php-parallel-lint": "^1.2",
|
||||
"phpstan\/phpstan-strict-rules": "^1.0",
|
||||
"phpunit\/phpunit": "^9.5"
|
||||
},
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "7.4.6"
|
||||
},
|
||||
"sort-packages": true
|
||||
},
|
||||
"extra": {
|
||||
"phpstan": {
|
||||
"includes": [
|
||||
"extension.neon",
|
||||
"rules.neon"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PHPStan\\": "src\/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"classmap": [
|
||||
"tests\/"
|
||||
]
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true
|
||||
}
|
66
vendor/phpstan/phpstan-phpunit/extension.neon
vendored
66
vendor/phpstan/phpstan-phpunit/extension.neon
vendored
|
@ -1,66 +0,0 @@
|
|||
parameters:
|
||||
phpunit:
|
||||
convertUnionToIntersectionType: true
|
||||
additionalConstructors:
|
||||
- PHPUnit\Framework\TestCase::setUp
|
||||
earlyTerminatingMethodCalls:
|
||||
PHPUnit\Framework\Assert:
|
||||
- fail
|
||||
- markTestIncomplete
|
||||
- markTestSkipped
|
||||
stubFiles:
|
||||
- stubs/InvocationMocker.stub
|
||||
- stubs/MockBuilder.stub
|
||||
- stubs/MockObject.stub
|
||||
- stubs/Stub.stub
|
||||
- stubs/TestCase.stub
|
||||
exceptions:
|
||||
uncheckedExceptionRegexes:
|
||||
- '#^PHPUnit\\#'
|
||||
- '#^SebastianBergmann\\#'
|
||||
|
||||
parametersSchema:
|
||||
phpunit: structure([
|
||||
convertUnionToIntersectionType: bool()
|
||||
])
|
||||
|
||||
services:
|
||||
-
|
||||
class: PHPStan\PhpDoc\PHPUnit\MockObjectTypeNodeResolverExtension
|
||||
-
|
||||
class: PHPStan\Type\PHPUnit\Assert\AssertFunctionTypeSpecifyingExtension
|
||||
tags:
|
||||
- phpstan.typeSpecifier.functionTypeSpecifyingExtension
|
||||
-
|
||||
class: PHPStan\Type\PHPUnit\Assert\AssertMethodTypeSpecifyingExtension
|
||||
tags:
|
||||
- phpstan.typeSpecifier.methodTypeSpecifyingExtension
|
||||
-
|
||||
class: PHPStan\Type\PHPUnit\Assert\AssertStaticMethodTypeSpecifyingExtension
|
||||
tags:
|
||||
- phpstan.typeSpecifier.staticMethodTypeSpecifyingExtension
|
||||
-
|
||||
class: PHPStan\Type\PHPUnit\InvocationMockerDynamicReturnTypeExtension
|
||||
tags:
|
||||
- phpstan.broker.dynamicMethodReturnTypeExtension
|
||||
-
|
||||
class: PHPStan\Type\PHPUnit\MockBuilderDynamicReturnTypeExtension
|
||||
tags:
|
||||
- phpstan.broker.dynamicMethodReturnTypeExtension
|
||||
-
|
||||
class: PHPStan\Type\PHPUnit\MockObjectDynamicReturnTypeExtension
|
||||
tags:
|
||||
- phpstan.broker.dynamicMethodReturnTypeExtension
|
||||
-
|
||||
class: PHPStan\Rules\PHPUnit\CoversHelper
|
||||
-
|
||||
class: PHPStan\Rules\PHPUnit\AnnotationHelper
|
||||
-
|
||||
class: PHPStan\Rules\PHPUnit\DataProviderHelper
|
||||
factory: @PHPStan\Rules\PHPUnit\DataProviderHelperFactory::create()
|
||||
-
|
||||
class: PHPStan\Rules\PHPUnit\DataProviderHelperFactory
|
||||
|
||||
conditionalTags:
|
||||
PHPStan\PhpDoc\PHPUnit\MockObjectTypeNodeResolverExtension:
|
||||
phpstan.phpDoc.typeNodeResolverExtension: %phpunit.convertUnionToIntersectionType%
|
29
vendor/phpstan/phpstan-phpunit/rules.neon
vendored
29
vendor/phpstan/phpstan-phpunit/rules.neon
vendored
|
@ -1,29 +0,0 @@
|
|||
rules:
|
||||
- PHPStan\Rules\PHPUnit\AssertSameBooleanExpectedRule
|
||||
- PHPStan\Rules\PHPUnit\AssertSameNullExpectedRule
|
||||
- PHPStan\Rules\PHPUnit\AssertSameWithCountRule
|
||||
- PHPStan\Rules\PHPUnit\MockMethodCallRule
|
||||
- PHPStan\Rules\PHPUnit\ShouldCallParentMethodsRule
|
||||
|
||||
services:
|
||||
- class: PHPStan\Rules\PHPUnit\ClassCoversExistsRule
|
||||
- class: PHPStan\Rules\PHPUnit\ClassMethodCoversExistsRule
|
||||
-
|
||||
class: PHPStan\Rules\PHPUnit\DataProviderDeclarationRule
|
||||
arguments:
|
||||
checkFunctionNameCase: %checkFunctionNameCase%
|
||||
deprecationRulesInstalled: %deprecationRulesInstalled%
|
||||
- class: PHPStan\Rules\PHPUnit\NoMissingSpaceInClassAnnotationRule
|
||||
- class: PHPStan\Rules\PHPUnit\NoMissingSpaceInMethodAnnotationRule
|
||||
|
||||
conditionalTags:
|
||||
PHPStan\Rules\PHPUnit\ClassCoversExistsRule:
|
||||
phpstan.rules.rule: %featureToggles.bleedingEdge%
|
||||
PHPStan\Rules\PHPUnit\ClassMethodCoversExistsRule:
|
||||
phpstan.rules.rule: %featureToggles.bleedingEdge%
|
||||
PHPStan\Rules\PHPUnit\DataProviderDeclarationRule:
|
||||
phpstan.rules.rule: %featureToggles.bleedingEdge%
|
||||
PHPStan\Rules\PHPUnit\NoMissingSpaceInClassAnnotationRule:
|
||||
phpstan.rules.rule: %featureToggles.bleedingEdge%
|
||||
PHPStan\Rules\PHPUnit\NoMissingSpaceInMethodAnnotationRule:
|
||||
phpstan.rules.rule: %featureToggles.bleedingEdge%
|
|
@ -1,51 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\PhpDoc\PHPUnit;
|
||||
|
||||
use PHPStan\Analyser\NameScope;
|
||||
use PHPStan\PhpDoc\TypeNodeResolver;
|
||||
use PHPStan\PhpDoc\TypeNodeResolverAwareExtension;
|
||||
use PHPStan\PhpDoc\TypeNodeResolverExtension;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\UnionTypeNode;
|
||||
use PHPStan\Type\NeverType;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\TypeCombinator;
|
||||
use function array_key_exists;
|
||||
use function count;
|
||||
class MockObjectTypeNodeResolverExtension implements TypeNodeResolverExtension, TypeNodeResolverAwareExtension
|
||||
{
|
||||
/** @var TypeNodeResolver */
|
||||
private $typeNodeResolver;
|
||||
public function setTypeNodeResolver(TypeNodeResolver $typeNodeResolver) : void
|
||||
{
|
||||
$this->typeNodeResolver = $typeNodeResolver;
|
||||
}
|
||||
public function getCacheKey() : string
|
||||
{
|
||||
return 'phpunit-v1';
|
||||
}
|
||||
public function resolve(TypeNode $typeNode, NameScope $nameScope) : ?Type
|
||||
{
|
||||
if (!$typeNode instanceof UnionTypeNode) {
|
||||
return null;
|
||||
}
|
||||
static $mockClassNames = ['PHPUnit_Framework_MockObject_MockObject' => \true, 'RectorPrefix202305\\PHPUnit\\Framework\\MockObject\\MockObject' => \true, 'RectorPrefix202305\\PHPUnit\\Framework\\MockObject\\Stub' => \true];
|
||||
$types = $this->typeNodeResolver->resolveMultiple($typeNode->types, $nameScope);
|
||||
foreach ($types as $type) {
|
||||
$classNames = $type->getObjectClassNames();
|
||||
if (count($classNames) !== 1) {
|
||||
continue;
|
||||
}
|
||||
if (array_key_exists($classNames[0], $mockClassNames)) {
|
||||
$resultType = TypeCombinator::intersect(...$types);
|
||||
if ($resultType instanceof NeverType) {
|
||||
continue;
|
||||
}
|
||||
return $resultType;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\Rules\PHPUnit;
|
||||
|
||||
use PhpParser\Comment\Doc;
|
||||
use PHPStan\Rules\RuleError;
|
||||
use PHPStan\Rules\RuleErrorBuilder;
|
||||
use function array_key_exists;
|
||||
use function in_array;
|
||||
use function preg_match;
|
||||
use function preg_split;
|
||||
class AnnotationHelper
|
||||
{
|
||||
private const ANNOTATIONS_WITH_PARAMS = ['backupGlobals', 'backupStaticAttributes', 'covers', 'coversDefaultClass', 'dataProvider', 'depends', 'group', 'preserveGlobalState', 'requires', 'testDox', 'testWith', 'ticket', 'uses'];
|
||||
/**
|
||||
* @return RuleError[] errors
|
||||
*/
|
||||
public function processDocComment(Doc $docComment) : array
|
||||
{
|
||||
$errors = [];
|
||||
$docCommentLines = preg_split("/((\r?\n)|(\r\n?))/", $docComment->getText());
|
||||
if ($docCommentLines === \false) {
|
||||
return [];
|
||||
}
|
||||
foreach ($docCommentLines as $docCommentLine) {
|
||||
// These annotations can't be retrieved using the getResolvedPhpDoc method on the FileTypeMapper as they are not present when they are invalid
|
||||
$annotation = preg_match('/(?<annotation>@(?<property>[a-zA-Z]+)(?<whitespace>\\s*)(?<value>.*))/', $docCommentLine, $matches);
|
||||
if ($annotation === \false) {
|
||||
continue;
|
||||
// Line without annotation
|
||||
}
|
||||
if (array_key_exists('property', $matches) === \false || array_key_exists('whitespace', $matches) === \false || array_key_exists('annotation', $matches) === \false) {
|
||||
continue;
|
||||
}
|
||||
if (!in_array($matches['property'], self::ANNOTATIONS_WITH_PARAMS, \true) || $matches['whitespace'] !== '') {
|
||||
continue;
|
||||
}
|
||||
$errors[] = RuleErrorBuilder::message('Annotation "' . $matches['annotation'] . '" is invalid, "@' . $matches['property'] . '" should be followed by a space and a value.')->build();
|
||||
}
|
||||
return $errors;
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\Rules\PHPUnit;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use function in_array;
|
||||
use function strtolower;
|
||||
class AssertRuleHelper
|
||||
{
|
||||
/**
|
||||
* @phpstan-assert-if-true Node\Expr\MethodCall|Node\Expr\StaticCall $node
|
||||
*/
|
||||
public static function isMethodOrStaticCallOnAssert(Node $node, Scope $scope) : bool
|
||||
{
|
||||
$testCaseType = new ObjectType('RectorPrefix202305\\PHPUnit\\Framework\\Assert');
|
||||
if ($node instanceof Node\Expr\MethodCall) {
|
||||
$calledOnType = $scope->getType($node->var);
|
||||
} elseif ($node instanceof Node\Expr\StaticCall) {
|
||||
if ($node->class instanceof Node\Name) {
|
||||
$class = (string) $node->class;
|
||||
if ($scope->isInClass() && in_array(strtolower($class), ['self', 'static', 'parent'], \true)) {
|
||||
$calledOnType = new ObjectType($scope->getClassReflection()->getName());
|
||||
} else {
|
||||
$calledOnType = new ObjectType($class);
|
||||
}
|
||||
} else {
|
||||
$calledOnType = $scope->getType($node->class);
|
||||
}
|
||||
} else {
|
||||
return \false;
|
||||
}
|
||||
if (!$testCaseType->isSuperTypeOf($calledOnType)->yes()) {
|
||||
return \false;
|
||||
}
|
||||
return \true;
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\Rules\PHPUnit;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\ConstFetch;
|
||||
use PhpParser\NodeAbstract;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Rules\Rule;
|
||||
use function count;
|
||||
/**
|
||||
* @implements Rule<NodeAbstract>
|
||||
*/
|
||||
class AssertSameBooleanExpectedRule implements Rule
|
||||
{
|
||||
public function getNodeType() : string
|
||||
{
|
||||
return NodeAbstract::class;
|
||||
}
|
||||
public function processNode(Node $node, Scope $scope) : array
|
||||
{
|
||||
if (!\PHPStan\Rules\PHPUnit\AssertRuleHelper::isMethodOrStaticCallOnAssert($node, $scope)) {
|
||||
return [];
|
||||
}
|
||||
if (count($node->getArgs()) < 2) {
|
||||
return [];
|
||||
}
|
||||
if (!$node->name instanceof Node\Identifier || $node->name->toLowerString() !== 'assertsame') {
|
||||
return [];
|
||||
}
|
||||
$expectedArgumentValue = $node->getArgs()[0]->value;
|
||||
if (!$expectedArgumentValue instanceof ConstFetch) {
|
||||
return [];
|
||||
}
|
||||
if ($expectedArgumentValue->name->toLowerString() === 'true') {
|
||||
return ['You should use assertTrue() instead of assertSame() when expecting "true"'];
|
||||
}
|
||||
if ($expectedArgumentValue->name->toLowerString() === 'false') {
|
||||
return ['You should use assertFalse() instead of assertSame() when expecting "false"'];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\Rules\PHPUnit;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\ConstFetch;
|
||||
use PhpParser\NodeAbstract;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Rules\Rule;
|
||||
use function count;
|
||||
/**
|
||||
* @implements Rule<NodeAbstract>
|
||||
*/
|
||||
class AssertSameNullExpectedRule implements Rule
|
||||
{
|
||||
public function getNodeType() : string
|
||||
{
|
||||
return NodeAbstract::class;
|
||||
}
|
||||
public function processNode(Node $node, Scope $scope) : array
|
||||
{
|
||||
if (!\PHPStan\Rules\PHPUnit\AssertRuleHelper::isMethodOrStaticCallOnAssert($node, $scope)) {
|
||||
return [];
|
||||
}
|
||||
if (count($node->getArgs()) < 2) {
|
||||
return [];
|
||||
}
|
||||
if (!$node->name instanceof Node\Identifier || $node->name->toLowerString() !== 'assertsame') {
|
||||
return [];
|
||||
}
|
||||
$expectedArgumentValue = $node->getArgs()[0]->value;
|
||||
if (!$expectedArgumentValue instanceof ConstFetch) {
|
||||
return [];
|
||||
}
|
||||
if ($expectedArgumentValue->name->toLowerString() === 'null') {
|
||||
return ['You should use assertNull() instead of assertSame(null, $actual).'];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\Rules\PHPUnit;
|
||||
|
||||
use Countable;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\NodeAbstract;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Rules\Rule;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use function count;
|
||||
/**
|
||||
* @implements Rule<NodeAbstract>
|
||||
*/
|
||||
class AssertSameWithCountRule implements Rule
|
||||
{
|
||||
public function getNodeType() : string
|
||||
{
|
||||
return NodeAbstract::class;
|
||||
}
|
||||
public function processNode(Node $node, Scope $scope) : array
|
||||
{
|
||||
if (!\PHPStan\Rules\PHPUnit\AssertRuleHelper::isMethodOrStaticCallOnAssert($node, $scope)) {
|
||||
return [];
|
||||
}
|
||||
if (count($node->getArgs()) < 2) {
|
||||
return [];
|
||||
}
|
||||
if (!$node->name instanceof Node\Identifier || $node->name->toLowerString() !== 'assertsame') {
|
||||
return [];
|
||||
}
|
||||
$right = $node->getArgs()[1]->value;
|
||||
if ($right instanceof Node\Expr\FuncCall && $right->name instanceof Node\Name && $right->name->toLowerString() === 'count') {
|
||||
return ['You should use assertCount($expectedCount, $variable) instead of assertSame($expectedCount, count($variable)).'];
|
||||
}
|
||||
if ($right instanceof Node\Expr\MethodCall && $right->name instanceof Node\Identifier && $right->name->toLowerString() === 'count' && count($right->getArgs()) === 0) {
|
||||
$type = $scope->getType($right->var);
|
||||
if ((new ObjectType(Countable::class))->isSuperTypeOf($type)->yes()) {
|
||||
return ['You should use assertCount($expectedCount, $variable) instead of assertSame($expectedCount, $variable->count()).'];
|
||||
}
|
||||
}
|
||||
return [];
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\Rules\PHPUnit;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Node\InClassNode;
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use PHPStan\Rules\Rule;
|
||||
use PHPStan\Rules\RuleErrorBuilder;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use function array_merge;
|
||||
use function array_shift;
|
||||
use function count;
|
||||
use function sprintf;
|
||||
/**
|
||||
* @implements Rule<InClassNode>
|
||||
*/
|
||||
class ClassCoversExistsRule implements Rule
|
||||
{
|
||||
/**
|
||||
* Covers helper.
|
||||
*
|
||||
* @var CoversHelper
|
||||
*/
|
||||
private $coversHelper;
|
||||
/**
|
||||
* Reflection provider.
|
||||
*
|
||||
* @var ReflectionProvider
|
||||
*/
|
||||
private $reflectionProvider;
|
||||
public function __construct(\PHPStan\Rules\PHPUnit\CoversHelper $coversHelper, ReflectionProvider $reflectionProvider)
|
||||
{
|
||||
$this->reflectionProvider = $reflectionProvider;
|
||||
$this->coversHelper = $coversHelper;
|
||||
}
|
||||
public function getNodeType() : string
|
||||
{
|
||||
return InClassNode::class;
|
||||
}
|
||||
public function processNode(Node $node, Scope $scope) : array
|
||||
{
|
||||
$classReflection = $node->getClassReflection();
|
||||
if (!$classReflection->isSubclassOf(TestCase::class)) {
|
||||
return [];
|
||||
}
|
||||
$errors = [];
|
||||
$classPhpDoc = $classReflection->getResolvedPhpDoc();
|
||||
[$classCovers, $classCoversDefaultClasses] = $this->coversHelper->getCoverAnnotations($classPhpDoc);
|
||||
if (count($classCoversDefaultClasses) >= 2) {
|
||||
$errors[] = RuleErrorBuilder::message(sprintf('@coversDefaultClass is defined multiple times.'))->build();
|
||||
return $errors;
|
||||
}
|
||||
$coversDefaultClass = array_shift($classCoversDefaultClasses);
|
||||
if ($coversDefaultClass !== null) {
|
||||
$className = (string) $coversDefaultClass->value;
|
||||
if (!$this->reflectionProvider->hasClass($className)) {
|
||||
$errors[] = RuleErrorBuilder::message(sprintf('@coversDefaultClass references an invalid class %s.', $className))->build();
|
||||
}
|
||||
}
|
||||
foreach ($classCovers as $covers) {
|
||||
$errors = array_merge($errors, $this->coversHelper->processCovers($node, $covers, null));
|
||||
}
|
||||
return $errors;
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\Rules\PHPUnit;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
|
||||
use PHPStan\Rules\Rule;
|
||||
use PHPStan\Rules\RuleErrorBuilder;
|
||||
use PHPStan\Type\FileTypeMapper;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use function array_map;
|
||||
use function array_merge;
|
||||
use function array_shift;
|
||||
use function count;
|
||||
use function in_array;
|
||||
use function sprintf;
|
||||
/**
|
||||
* @implements Rule<Node\Stmt\ClassMethod>
|
||||
*/
|
||||
class ClassMethodCoversExistsRule implements Rule
|
||||
{
|
||||
/**
|
||||
* Covers helper.
|
||||
*
|
||||
* @var CoversHelper
|
||||
*/
|
||||
private $coversHelper;
|
||||
/**
|
||||
* The file type mapper.
|
||||
*
|
||||
* @var FileTypeMapper
|
||||
*/
|
||||
private $fileTypeMapper;
|
||||
public function __construct(\PHPStan\Rules\PHPUnit\CoversHelper $coversHelper, FileTypeMapper $fileTypeMapper)
|
||||
{
|
||||
$this->coversHelper = $coversHelper;
|
||||
$this->fileTypeMapper = $fileTypeMapper;
|
||||
}
|
||||
public function getNodeType() : string
|
||||
{
|
||||
return Node\Stmt\ClassMethod::class;
|
||||
}
|
||||
public function processNode(Node $node, Scope $scope) : array
|
||||
{
|
||||
$classReflection = $scope->getClassReflection();
|
||||
if ($classReflection === null) {
|
||||
return [];
|
||||
}
|
||||
if (!$classReflection->isSubclassOf(TestCase::class)) {
|
||||
return [];
|
||||
}
|
||||
$errors = [];
|
||||
$classPhpDoc = $classReflection->getResolvedPhpDoc();
|
||||
[$classCovers, $classCoversDefaultClasses] = $this->coversHelper->getCoverAnnotations($classPhpDoc);
|
||||
$classCoversStrings = array_map(static function (PhpDocTagNode $covers) : string {
|
||||
return (string) $covers->value;
|
||||
}, $classCovers);
|
||||
$docComment = $node->getDocComment();
|
||||
if ($docComment === null) {
|
||||
return [];
|
||||
}
|
||||
$coversDefaultClass = count($classCoversDefaultClasses) === 1 ? array_shift($classCoversDefaultClasses) : null;
|
||||
$methodPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($scope->getFile(), $classReflection->getName(), $scope->isInTrait() ? $scope->getTraitReflection()->getName() : null, $node->name->toString(), $docComment->getText());
|
||||
[$methodCovers, $methodCoversDefaultClasses] = $this->coversHelper->getCoverAnnotations($methodPhpDoc);
|
||||
$errors = [];
|
||||
if (count($methodCoversDefaultClasses) > 0) {
|
||||
$errors[] = RuleErrorBuilder::message(sprintf('@coversDefaultClass defined on class method %s.', $node->name))->build();
|
||||
}
|
||||
foreach ($methodCovers as $covers) {
|
||||
if (in_array((string) $covers->value, $classCoversStrings, \true)) {
|
||||
$errors[] = RuleErrorBuilder::message(sprintf('Class already @covers %s so the method @covers is redundant.', $covers->value))->build();
|
||||
}
|
||||
$errors = array_merge($errors, $this->coversHelper->processCovers($node, $covers, $coversDefaultClass));
|
||||
}
|
||||
return $errors;
|
||||
}
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\Rules\PHPUnit;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Name;
|
||||
use PHPStan\PhpDoc\ResolvedPhpDocBlock;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use PHPStan\Rules\RuleError;
|
||||
use PHPStan\Rules\RuleErrorBuilder;
|
||||
use function array_merge;
|
||||
use function explode;
|
||||
use function sprintf;
|
||||
use function strpos;
|
||||
class CoversHelper
|
||||
{
|
||||
/**
|
||||
* Reflection provider.
|
||||
*
|
||||
* @var ReflectionProvider
|
||||
*/
|
||||
private $reflectionProvider;
|
||||
public function __construct(ReflectionProvider $reflectionProvider)
|
||||
{
|
||||
$this->reflectionProvider = $reflectionProvider;
|
||||
}
|
||||
/**
|
||||
* Gathers @covers and @coversDefaultClass annotations from phpdocs.
|
||||
*
|
||||
* @return array{PhpDocTagNode[], PhpDocTagNode[]}
|
||||
*/
|
||||
public function getCoverAnnotations(?ResolvedPhpDocBlock $phpDoc) : array
|
||||
{
|
||||
if ($phpDoc === null) {
|
||||
return [[], []];
|
||||
}
|
||||
$phpDocNodes = $phpDoc->getPhpDocNodes();
|
||||
$covers = [];
|
||||
$coversDefaultClasses = [];
|
||||
foreach ($phpDocNodes as $docNode) {
|
||||
$covers = array_merge($covers, $docNode->getTagsByName('@covers'));
|
||||
$coversDefaultClasses = array_merge($coversDefaultClasses, $docNode->getTagsByName('@coversDefaultClass'));
|
||||
}
|
||||
return [$covers, $coversDefaultClasses];
|
||||
}
|
||||
/**
|
||||
* @return RuleError[] errors
|
||||
*/
|
||||
public function processCovers(Node $node, PhpDocTagNode $phpDocTag, ?PhpDocTagNode $coversDefaultClass) : array
|
||||
{
|
||||
$errors = [];
|
||||
$covers = (string) $phpDocTag->value;
|
||||
if ($covers === '') {
|
||||
$errors[] = RuleErrorBuilder::message('@covers value does not specify anything.')->build();
|
||||
return $errors;
|
||||
}
|
||||
$isMethod = strpos($covers, '::') !== \false;
|
||||
$fullName = $covers;
|
||||
if ($isMethod) {
|
||||
[$className, $method] = explode('::', $covers);
|
||||
} else {
|
||||
$className = $covers;
|
||||
}
|
||||
if ($className === '' && $node instanceof Node\Stmt\ClassMethod && $coversDefaultClass !== null) {
|
||||
$className = (string) $coversDefaultClass->value;
|
||||
$fullName = $className . $covers;
|
||||
}
|
||||
if ($this->reflectionProvider->hasClass($className)) {
|
||||
$class = $this->reflectionProvider->getClass($className);
|
||||
if ($class->isInterface()) {
|
||||
$errors[] = RuleErrorBuilder::message(sprintf('@covers value %s references an interface.', $fullName))->build();
|
||||
}
|
||||
if (isset($method) && $method !== '' && !$class->hasMethod($method)) {
|
||||
$errors[] = RuleErrorBuilder::message(sprintf('@covers value %s references an invalid method.', $fullName))->build();
|
||||
}
|
||||
} elseif (isset($method) && $this->reflectionProvider->hasFunction(new Name($method, []), null)) {
|
||||
return $errors;
|
||||
} elseif (!isset($method) && $this->reflectionProvider->hasFunction(new Name($className, []), null)) {
|
||||
return $errors;
|
||||
} else {
|
||||
$error = RuleErrorBuilder::message(sprintf('@covers value %s references an invalid %s.', $fullName, $isMethod ? 'method' : 'class or function'));
|
||||
if (strpos($className, '\\') === \false) {
|
||||
$error->tip('The @covers annotation requires a fully qualified name.');
|
||||
}
|
||||
$errors[] = $error->build();
|
||||
}
|
||||
return $errors;
|
||||
}
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\Rules\PHPUnit;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Rules\Rule;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use function array_merge;
|
||||
/**
|
||||
* @implements Rule<Node\Stmt\ClassMethod>
|
||||
*/
|
||||
class DataProviderDeclarationRule implements Rule
|
||||
{
|
||||
/**
|
||||
* Data provider helper.
|
||||
*
|
||||
* @var DataProviderHelper
|
||||
*/
|
||||
private $dataProviderHelper;
|
||||
/**
|
||||
* When set to true, it reports data provider method with incorrect name case.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $checkFunctionNameCase;
|
||||
/**
|
||||
* When phpstan-deprecation-rules is installed, it reports deprecated usages.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $deprecationRulesInstalled;
|
||||
public function __construct(\PHPStan\Rules\PHPUnit\DataProviderHelper $dataProviderHelper, bool $checkFunctionNameCase, bool $deprecationRulesInstalled)
|
||||
{
|
||||
$this->dataProviderHelper = $dataProviderHelper;
|
||||
$this->checkFunctionNameCase = $checkFunctionNameCase;
|
||||
$this->deprecationRulesInstalled = $deprecationRulesInstalled;
|
||||
}
|
||||
public function getNodeType() : string
|
||||
{
|
||||
return Node\Stmt\ClassMethod::class;
|
||||
}
|
||||
public function processNode(Node $node, Scope $scope) : array
|
||||
{
|
||||
$classReflection = $scope->getClassReflection();
|
||||
if ($classReflection === null || !$classReflection->isSubclassOf(TestCase::class)) {
|
||||
return [];
|
||||
}
|
||||
$errors = [];
|
||||
foreach ($this->dataProviderHelper->getDataProviderMethods($scope, $node, $classReflection) as $dataProviderValue => [$dataProviderClassReflection, $dataProviderMethodName, $lineNumber]) {
|
||||
$errors = array_merge($errors, $this->dataProviderHelper->processDataProvider($dataProviderValue, $dataProviderClassReflection, $dataProviderMethodName, $lineNumber, $this->checkFunctionNameCase, $this->deprecationRulesInstalled));
|
||||
}
|
||||
return $errors;
|
||||
}
|
||||
}
|
|
@ -1,188 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\Rules\PHPUnit;
|
||||
|
||||
use PhpParser\Node\Attribute;
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\PhpDoc\ResolvedPhpDocBlock;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use PHPStan\Reflection\MissingMethodFromReflectionException;
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use PHPStan\Rules\RuleError;
|
||||
use PHPStan\Rules\RuleErrorBuilder;
|
||||
use PHPStan\Type\FileTypeMapper;
|
||||
use function array_merge;
|
||||
use function count;
|
||||
use function explode;
|
||||
use function preg_match;
|
||||
use function sprintf;
|
||||
class DataProviderHelper
|
||||
{
|
||||
/**
|
||||
* Reflection provider.
|
||||
*
|
||||
* @var ReflectionProvider
|
||||
*/
|
||||
private $reflectionProvider;
|
||||
/**
|
||||
* The file type mapper.
|
||||
*
|
||||
* @var FileTypeMapper
|
||||
*/
|
||||
private $fileTypeMapper;
|
||||
/** @var bool */
|
||||
private $phpunit10OrNewer;
|
||||
public function __construct(ReflectionProvider $reflectionProvider, FileTypeMapper $fileTypeMapper, bool $phpunit10OrNewer)
|
||||
{
|
||||
$this->reflectionProvider = $reflectionProvider;
|
||||
$this->fileTypeMapper = $fileTypeMapper;
|
||||
$this->phpunit10OrNewer = $phpunit10OrNewer;
|
||||
}
|
||||
/**
|
||||
* @return iterable<array{ClassReflection|null, string, int}>
|
||||
*/
|
||||
public function getDataProviderMethods(Scope $scope, ClassMethod $node, ClassReflection $classReflection) : iterable
|
||||
{
|
||||
$docComment = $node->getDocComment();
|
||||
if ($docComment !== null) {
|
||||
$methodPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($scope->getFile(), $classReflection->getName(), $scope->isInTrait() ? $scope->getTraitReflection()->getName() : null, $node->name->toString(), $docComment->getText());
|
||||
foreach ($this->getDataProviderAnnotations($methodPhpDoc) as $annotation) {
|
||||
$dataProviderValue = $this->getDataProviderAnnotationValue($annotation);
|
||||
if ($dataProviderValue === null) {
|
||||
// Missing value is already handled in NoMissingSpaceInMethodAnnotationRule
|
||||
continue;
|
||||
}
|
||||
$dataProviderMethod = $this->parseDataProviderAnnotationValue($scope, $dataProviderValue);
|
||||
$dataProviderMethod[] = $node->getLine();
|
||||
(yield $dataProviderValue => $dataProviderMethod);
|
||||
}
|
||||
}
|
||||
if (!$this->phpunit10OrNewer) {
|
||||
return;
|
||||
}
|
||||
foreach ($node->attrGroups as $attrGroup) {
|
||||
foreach ($attrGroup->attrs as $attr) {
|
||||
$dataProviderMethod = null;
|
||||
if ($attr->name->toLowerString() === 'phpunit\\framework\\attributes\\dataprovider') {
|
||||
$dataProviderMethod = $this->parseDataProviderAttribute($attr, $classReflection);
|
||||
} elseif ($attr->name->toLowerString() === 'phpunit\\framework\\attributes\\dataproviderexternal') {
|
||||
$dataProviderMethod = $this->parseDataProviderExternalAttribute($attr);
|
||||
}
|
||||
if ($dataProviderMethod === null) {
|
||||
continue;
|
||||
}
|
||||
yield from $dataProviderMethod;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @return array<PhpDocTagNode>
|
||||
*/
|
||||
private function getDataProviderAnnotations(?ResolvedPhpDocBlock $phpDoc) : array
|
||||
{
|
||||
if ($phpDoc === null) {
|
||||
return [];
|
||||
}
|
||||
$phpDocNodes = $phpDoc->getPhpDocNodes();
|
||||
$annotations = [];
|
||||
foreach ($phpDocNodes as $docNode) {
|
||||
$annotations = array_merge($annotations, $docNode->getTagsByName('@dataProvider'));
|
||||
}
|
||||
return $annotations;
|
||||
}
|
||||
/**
|
||||
* @return RuleError[] errors
|
||||
*/
|
||||
public function processDataProvider(string $dataProviderValue, ?ClassReflection $classReflection, string $methodName, int $lineNumber, bool $checkFunctionNameCase, bool $deprecationRulesInstalled) : array
|
||||
{
|
||||
if ($classReflection === null) {
|
||||
$error = RuleErrorBuilder::message(sprintf('@dataProvider %s related class not found.', $dataProviderValue))->line($lineNumber)->build();
|
||||
return [$error];
|
||||
}
|
||||
try {
|
||||
$dataProviderMethodReflection = $classReflection->getNativeMethod($methodName);
|
||||
} catch (MissingMethodFromReflectionException $missingMethodFromReflectionException) {
|
||||
$error = RuleErrorBuilder::message(sprintf('@dataProvider %s related method not found.', $dataProviderValue))->line($lineNumber)->build();
|
||||
return [$error];
|
||||
}
|
||||
$errors = [];
|
||||
if ($checkFunctionNameCase && $methodName !== $dataProviderMethodReflection->getName()) {
|
||||
$errors[] = RuleErrorBuilder::message(sprintf('@dataProvider %s related method is used with incorrect case: %s.', $dataProviderValue, $dataProviderMethodReflection->getName()))->line($lineNumber)->build();
|
||||
}
|
||||
if (!$dataProviderMethodReflection->isPublic()) {
|
||||
$errors[] = RuleErrorBuilder::message(sprintf('@dataProvider %s related method must be public.', $dataProviderValue))->line($lineNumber)->build();
|
||||
}
|
||||
if ($deprecationRulesInstalled && $this->phpunit10OrNewer && !$dataProviderMethodReflection->isStatic()) {
|
||||
$errors[] = RuleErrorBuilder::message(sprintf('@dataProvider %s related method must be static in PHPUnit 10 and newer.', $dataProviderValue))->line($lineNumber)->build();
|
||||
}
|
||||
return $errors;
|
||||
}
|
||||
private function getDataProviderAnnotationValue(PhpDocTagNode $phpDocTag) : ?string
|
||||
{
|
||||
if (preg_match('/^[^ \\t]+/', (string) $phpDocTag->value, $matches) !== 1) {
|
||||
return null;
|
||||
}
|
||||
return $matches[0];
|
||||
}
|
||||
/**
|
||||
* @return array{ClassReflection|null, string}
|
||||
*/
|
||||
private function parseDataProviderAnnotationValue(Scope $scope, string $dataProviderValue) : array
|
||||
{
|
||||
$parts = explode('::', $dataProviderValue, 2);
|
||||
if (count($parts) <= 1) {
|
||||
return [$scope->getClassReflection(), $dataProviderValue];
|
||||
}
|
||||
if ($this->reflectionProvider->hasClass($parts[0])) {
|
||||
return [$this->reflectionProvider->getClass($parts[0]), $parts[1]];
|
||||
}
|
||||
return [null, $dataProviderValue];
|
||||
}
|
||||
/**
|
||||
* @return array<string, array{(ClassReflection|null), string, int}>|null
|
||||
*/
|
||||
private function parseDataProviderExternalAttribute(Attribute $attribute) : ?array
|
||||
{
|
||||
if (count($attribute->args) !== 2) {
|
||||
return null;
|
||||
}
|
||||
$methodNameArg = $attribute->args[1]->value;
|
||||
if (!$methodNameArg instanceof String_) {
|
||||
return null;
|
||||
}
|
||||
$classNameArg = $attribute->args[0]->value;
|
||||
if ($classNameArg instanceof ClassConstFetch && $classNameArg->class instanceof Name) {
|
||||
$className = $classNameArg->class->toString();
|
||||
} elseif ($classNameArg instanceof String_) {
|
||||
$className = $classNameArg->value;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
$dataProviderClassReflection = null;
|
||||
if ($this->reflectionProvider->hasClass($className)) {
|
||||
$dataProviderClassReflection = $this->reflectionProvider->getClass($className);
|
||||
$className = $dataProviderClassReflection->getName();
|
||||
}
|
||||
return [sprintf('%s::%s', $className, $methodNameArg->value) => [$dataProviderClassReflection, $methodNameArg->value, $attribute->getLine()]];
|
||||
}
|
||||
/**
|
||||
* @return array<string, array{(ClassReflection|null), string, int}>|null
|
||||
*/
|
||||
private function parseDataProviderAttribute(Attribute $attribute, ClassReflection $classReflection) : ?array
|
||||
{
|
||||
if (count($attribute->args) !== 1) {
|
||||
return null;
|
||||
}
|
||||
$methodNameArg = $attribute->args[0]->value;
|
||||
if (!$methodNameArg instanceof String_) {
|
||||
return null;
|
||||
}
|
||||
return [$methodNameArg->value => [$classReflection, $methodNameArg->value, $attribute->getLine()]];
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\Rules\PHPUnit;
|
||||
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use PHPStan\Type\FileTypeMapper;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use function dirname;
|
||||
use function explode;
|
||||
use function file_get_contents;
|
||||
use function is_file;
|
||||
use function json_decode;
|
||||
class DataProviderHelperFactory
|
||||
{
|
||||
/** @var ReflectionProvider */
|
||||
private $reflectionProvider;
|
||||
/** @var FileTypeMapper */
|
||||
private $fileTypeMapper;
|
||||
public function __construct(ReflectionProvider $reflectionProvider, FileTypeMapper $fileTypeMapper)
|
||||
{
|
||||
$this->reflectionProvider = $reflectionProvider;
|
||||
$this->fileTypeMapper = $fileTypeMapper;
|
||||
}
|
||||
public function create() : \PHPStan\Rules\PHPUnit\DataProviderHelper
|
||||
{
|
||||
$phpUnit10OrNewer = \false;
|
||||
if ($this->reflectionProvider->hasClass(TestCase::class)) {
|
||||
$testCase = $this->reflectionProvider->getClass(TestCase::class);
|
||||
$file = $testCase->getFileName();
|
||||
if ($file !== null) {
|
||||
$phpUnitRoot = dirname($file, 3);
|
||||
$phpUnitComposer = $phpUnitRoot . '/composer.json';
|
||||
if (is_file($phpUnitComposer)) {
|
||||
$composerJson = @file_get_contents($phpUnitComposer);
|
||||
if ($composerJson !== \false) {
|
||||
$json = json_decode($composerJson, \true);
|
||||
$version = $json['extra']['branch-alias']['dev-main'] ?? null;
|
||||
if ($version !== null) {
|
||||
$majorVersion = (int) explode('.', $version)[0];
|
||||
if ($majorVersion >= 10) {
|
||||
$phpUnit10OrNewer = \true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new \PHPStan\Rules\PHPUnit\DataProviderHelper($this->reflectionProvider, $this->fileTypeMapper, $phpUnit10OrNewer);
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\Rules\PHPUnit;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Rules\Rule;
|
||||
use RectorPrefix202305\PHPUnit\Framework\MockObject\Builder\InvocationMocker;
|
||||
use RectorPrefix202305\PHPUnit\Framework\MockObject\MockObject;
|
||||
use RectorPrefix202305\PHPUnit\Framework\MockObject\Stub;
|
||||
use function array_filter;
|
||||
use function count;
|
||||
use function implode;
|
||||
use function in_array;
|
||||
use function sprintf;
|
||||
/**
|
||||
* @implements Rule<MethodCall>
|
||||
*/
|
||||
class MockMethodCallRule implements Rule
|
||||
{
|
||||
public function getNodeType() : string
|
||||
{
|
||||
return Node\Expr\MethodCall::class;
|
||||
}
|
||||
public function processNode(Node $node, Scope $scope) : array
|
||||
{
|
||||
/** @var Node\Expr\MethodCall $node */
|
||||
$node = $node;
|
||||
if (!$node->name instanceof Node\Identifier || $node->name->name !== 'method') {
|
||||
return [];
|
||||
}
|
||||
if (count($node->getArgs()) < 1) {
|
||||
return [];
|
||||
}
|
||||
$argType = $scope->getType($node->getArgs()[0]->value);
|
||||
if (count($argType->getConstantStrings()) === 0) {
|
||||
return [];
|
||||
}
|
||||
$errors = [];
|
||||
foreach ($argType->getConstantStrings() as $constantString) {
|
||||
$method = $constantString->getValue();
|
||||
$type = $scope->getType($node->var);
|
||||
if ((in_array(MockObject::class, $type->getObjectClassNames(), \true) || in_array(Stub::class, $type->getObjectClassNames(), \true)) && !$type->hasMethod($method)->yes()) {
|
||||
$mockClasses = array_filter($type->getObjectClassNames(), static function (string $class) : bool {
|
||||
return $class !== MockObject::class && $class !== Stub::class;
|
||||
});
|
||||
if (count($mockClasses) === 0) {
|
||||
continue;
|
||||
}
|
||||
$errors[] = sprintf('Trying to mock an undefined method %s() on class %s.', $method, implode('&', $mockClasses));
|
||||
continue;
|
||||
}
|
||||
$mockedClassObject = $type->getTemplateType(InvocationMocker::class, 'TMockedClass');
|
||||
if ($mockedClassObject->hasMethod($method)->yes()) {
|
||||
continue;
|
||||
}
|
||||
$classNames = $mockedClassObject->getObjectClassNames();
|
||||
if (count($classNames) === 0) {
|
||||
continue;
|
||||
}
|
||||
$errors[] = sprintf('Trying to mock an undefined method %s() on class %s.', $method, implode('|', $classNames));
|
||||
}
|
||||
return $errors;
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\Rules\PHPUnit;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Node\InClassNode;
|
||||
use PHPStan\Rules\Rule;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
/**
|
||||
* @implements Rule<InClassNode>
|
||||
*/
|
||||
class NoMissingSpaceInClassAnnotationRule implements Rule
|
||||
{
|
||||
/**
|
||||
* Covers helper.
|
||||
*
|
||||
* @var AnnotationHelper
|
||||
*/
|
||||
private $annotationHelper;
|
||||
public function __construct(\PHPStan\Rules\PHPUnit\AnnotationHelper $annotationHelper)
|
||||
{
|
||||
$this->annotationHelper = $annotationHelper;
|
||||
}
|
||||
public function getNodeType() : string
|
||||
{
|
||||
return InClassNode::class;
|
||||
}
|
||||
public function processNode(Node $node, Scope $scope) : array
|
||||
{
|
||||
$classReflection = $scope->getClassReflection();
|
||||
if ($classReflection === null || $classReflection->isSubclassOf(TestCase::class) === \false) {
|
||||
return [];
|
||||
}
|
||||
$docComment = $node->getDocComment();
|
||||
if ($docComment === null) {
|
||||
return [];
|
||||
}
|
||||
return $this->annotationHelper->processDocComment($docComment);
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\Rules\PHPUnit;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Node\InClassMethodNode;
|
||||
use PHPStan\Rules\Rule;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
/**
|
||||
* @implements Rule<InClassMethodNode>
|
||||
*/
|
||||
class NoMissingSpaceInMethodAnnotationRule implements Rule
|
||||
{
|
||||
/**
|
||||
* Covers helper.
|
||||
*
|
||||
* @var AnnotationHelper
|
||||
*/
|
||||
private $annotationHelper;
|
||||
public function __construct(\PHPStan\Rules\PHPUnit\AnnotationHelper $annotationHelper)
|
||||
{
|
||||
$this->annotationHelper = $annotationHelper;
|
||||
}
|
||||
public function getNodeType() : string
|
||||
{
|
||||
return InClassMethodNode::class;
|
||||
}
|
||||
public function processNode(Node $node, Scope $scope) : array
|
||||
{
|
||||
$classReflection = $scope->getClassReflection();
|
||||
if ($classReflection === null || $classReflection->isSubclassOf(TestCase::class) === \false) {
|
||||
return [];
|
||||
}
|
||||
$docComment = $node->getDocComment();
|
||||
if ($docComment === null) {
|
||||
return [];
|
||||
}
|
||||
return $this->annotationHelper->processDocComment($docComment);
|
||||
}
|
||||
}
|
|
@ -1,85 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\Rules\PHPUnit;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Node\InClassMethodNode;
|
||||
use PHPStan\Rules\Rule;
|
||||
use PHPStan\Rules\RuleErrorBuilder;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use function in_array;
|
||||
use function sprintf;
|
||||
use function strtolower;
|
||||
/**
|
||||
* @implements Rule<InClassMethodNode>
|
||||
*/
|
||||
class ShouldCallParentMethodsRule implements Rule
|
||||
{
|
||||
public function getNodeType() : string
|
||||
{
|
||||
return InClassMethodNode::class;
|
||||
}
|
||||
public function processNode(Node $node, Scope $scope) : array
|
||||
{
|
||||
$methodName = $node->getOriginalNode()->name->name;
|
||||
if (!in_array(strtolower($methodName), ['setup', 'teardown'], \true)) {
|
||||
return [];
|
||||
}
|
||||
if ($scope->getClassReflection() === null) {
|
||||
return [];
|
||||
}
|
||||
if (!$scope->getClassReflection()->isSubclassOf(TestCase::class)) {
|
||||
return [];
|
||||
}
|
||||
$parentClass = $scope->getClassReflection()->getParentClass();
|
||||
if ($parentClass === null) {
|
||||
return [];
|
||||
}
|
||||
if (!$parentClass->hasNativeMethod($methodName)) {
|
||||
return [];
|
||||
}
|
||||
$parentMethod = $parentClass->getNativeMethod($methodName);
|
||||
if ($parentMethod->getDeclaringClass()->getName() === TestCase::class) {
|
||||
return [];
|
||||
}
|
||||
$hasParentCall = $this->hasParentClassCall($node->getOriginalNode()->getStmts(), strtolower($methodName));
|
||||
if (!$hasParentCall) {
|
||||
return [RuleErrorBuilder::message(sprintf('Missing call to parent::%s() method.', $methodName))->build()];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
/**
|
||||
* @param Node\Stmt[]|null $stmts
|
||||
*
|
||||
*/
|
||||
private function hasParentClassCall(?array $stmts, string $methodName) : bool
|
||||
{
|
||||
if ($stmts === null) {
|
||||
return \false;
|
||||
}
|
||||
foreach ($stmts as $stmt) {
|
||||
if (!$stmt instanceof Node\Stmt\Expression) {
|
||||
continue;
|
||||
}
|
||||
if (!$stmt->expr instanceof Node\Expr\StaticCall) {
|
||||
continue;
|
||||
}
|
||||
if (!$stmt->expr->class instanceof Node\Name) {
|
||||
continue;
|
||||
}
|
||||
$class = (string) $stmt->expr->class;
|
||||
if (strtolower($class) !== 'parent') {
|
||||
continue;
|
||||
}
|
||||
if (!$stmt->expr->name instanceof Node\Identifier) {
|
||||
continue;
|
||||
}
|
||||
if ($stmt->expr->name->toLowerString() === $methodName) {
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\Type\PHPUnit\Assert;
|
||||
|
||||
use PhpParser\Node\Expr\FuncCall;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Analyser\SpecifiedTypes;
|
||||
use PHPStan\Analyser\TypeSpecifier;
|
||||
use PHPStan\Analyser\TypeSpecifierAwareExtension;
|
||||
use PHPStan\Analyser\TypeSpecifierContext;
|
||||
use PHPStan\Reflection\FunctionReflection;
|
||||
use PHPStan\Type\FunctionTypeSpecifyingExtension;
|
||||
use function strlen;
|
||||
use function strpos;
|
||||
use function substr;
|
||||
class AssertFunctionTypeSpecifyingExtension implements FunctionTypeSpecifyingExtension, TypeSpecifierAwareExtension
|
||||
{
|
||||
/** @var TypeSpecifier */
|
||||
private $typeSpecifier;
|
||||
public function setTypeSpecifier(TypeSpecifier $typeSpecifier) : void
|
||||
{
|
||||
$this->typeSpecifier = $typeSpecifier;
|
||||
}
|
||||
public function isFunctionSupported(FunctionReflection $functionReflection, FuncCall $node, TypeSpecifierContext $context) : bool
|
||||
{
|
||||
return \PHPStan\Type\PHPUnit\Assert\AssertTypeSpecifyingExtensionHelper::isSupported($this->trimName($functionReflection->getName()), $node->getArgs());
|
||||
}
|
||||
public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context) : SpecifiedTypes
|
||||
{
|
||||
return \PHPStan\Type\PHPUnit\Assert\AssertTypeSpecifyingExtensionHelper::specifyTypes($this->typeSpecifier, $scope, $this->trimName($functionReflection->getName()), $node->getArgs());
|
||||
}
|
||||
private function trimName(string $functionName) : string
|
||||
{
|
||||
$prefix = 'PHPUnit\\Framework\\';
|
||||
if (strpos($functionName, $prefix) === 0) {
|
||||
return substr($functionName, strlen($prefix));
|
||||
}
|
||||
return $functionName;
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\Type\PHPUnit\Assert;
|
||||
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Analyser\SpecifiedTypes;
|
||||
use PHPStan\Analyser\TypeSpecifier;
|
||||
use PHPStan\Analyser\TypeSpecifierAwareExtension;
|
||||
use PHPStan\Analyser\TypeSpecifierContext;
|
||||
use PHPStan\Reflection\MethodReflection;
|
||||
use PHPStan\Type\MethodTypeSpecifyingExtension;
|
||||
class AssertMethodTypeSpecifyingExtension implements MethodTypeSpecifyingExtension, TypeSpecifierAwareExtension
|
||||
{
|
||||
/** @var TypeSpecifier */
|
||||
private $typeSpecifier;
|
||||
public function setTypeSpecifier(TypeSpecifier $typeSpecifier) : void
|
||||
{
|
||||
$this->typeSpecifier = $typeSpecifier;
|
||||
}
|
||||
public function getClass() : string
|
||||
{
|
||||
return 'RectorPrefix202305\\PHPUnit\\Framework\\Assert';
|
||||
}
|
||||
public function isMethodSupported(MethodReflection $methodReflection, MethodCall $node, TypeSpecifierContext $context) : bool
|
||||
{
|
||||
return \PHPStan\Type\PHPUnit\Assert\AssertTypeSpecifyingExtensionHelper::isSupported($methodReflection->getName(), $node->getArgs());
|
||||
}
|
||||
public function specifyTypes(MethodReflection $functionReflection, MethodCall $node, Scope $scope, TypeSpecifierContext $context) : SpecifiedTypes
|
||||
{
|
||||
return \PHPStan\Type\PHPUnit\Assert\AssertTypeSpecifyingExtensionHelper::specifyTypes($this->typeSpecifier, $scope, $functionReflection->getName(), $node->getArgs());
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\Type\PHPUnit\Assert;
|
||||
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Analyser\SpecifiedTypes;
|
||||
use PHPStan\Analyser\TypeSpecifier;
|
||||
use PHPStan\Analyser\TypeSpecifierAwareExtension;
|
||||
use PHPStan\Analyser\TypeSpecifierContext;
|
||||
use PHPStan\Reflection\MethodReflection;
|
||||
use PHPStan\Type\StaticMethodTypeSpecifyingExtension;
|
||||
class AssertStaticMethodTypeSpecifyingExtension implements StaticMethodTypeSpecifyingExtension, TypeSpecifierAwareExtension
|
||||
{
|
||||
/** @var TypeSpecifier */
|
||||
private $typeSpecifier;
|
||||
public function setTypeSpecifier(TypeSpecifier $typeSpecifier) : void
|
||||
{
|
||||
$this->typeSpecifier = $typeSpecifier;
|
||||
}
|
||||
public function getClass() : string
|
||||
{
|
||||
return 'RectorPrefix202305\\PHPUnit\\Framework\\Assert';
|
||||
}
|
||||
public function isStaticMethodSupported(MethodReflection $methodReflection, StaticCall $node, TypeSpecifierContext $context) : bool
|
||||
{
|
||||
return \PHPStan\Type\PHPUnit\Assert\AssertTypeSpecifyingExtensionHelper::isSupported($methodReflection->getName(), $node->getArgs());
|
||||
}
|
||||
public function specifyTypes(MethodReflection $functionReflection, StaticCall $node, Scope $scope, TypeSpecifierContext $context) : SpecifiedTypes
|
||||
{
|
||||
return \PHPStan\Type\PHPUnit\Assert\AssertTypeSpecifyingExtensionHelper::specifyTypes($this->typeSpecifier, $scope, $functionReflection->getName(), $node->getArgs());
|
||||
}
|
||||
}
|
|
@ -1,188 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\Type\PHPUnit\Assert;
|
||||
|
||||
use Closure;
|
||||
use Countable;
|
||||
use EmptyIterator;
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\BinaryOp\Identical;
|
||||
use PhpParser\Node\Expr\BooleanNot;
|
||||
use PhpParser\Node\Expr\ConstFetch;
|
||||
use PhpParser\Node\Expr\FuncCall;
|
||||
use PhpParser\Node\Expr\Instanceof_;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Scalar\LNumber;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Analyser\SpecifiedTypes;
|
||||
use PHPStan\Analyser\TypeSpecifier;
|
||||
use PHPStan\Analyser\TypeSpecifierContext;
|
||||
use ReflectionObject;
|
||||
use function array_key_exists;
|
||||
use function count;
|
||||
use function strlen;
|
||||
use function strpos;
|
||||
use function substr;
|
||||
class AssertTypeSpecifyingExtensionHelper
|
||||
{
|
||||
/** @var Closure[] */
|
||||
private static $resolvers;
|
||||
/**
|
||||
* @param Arg[] $args
|
||||
*/
|
||||
public static function isSupported(string $name, array $args) : bool
|
||||
{
|
||||
$trimmedName = self::trimName($name);
|
||||
$resolvers = self::getExpressionResolvers();
|
||||
if (!array_key_exists($trimmedName, $resolvers)) {
|
||||
return \false;
|
||||
}
|
||||
$resolver = $resolvers[$trimmedName];
|
||||
$resolverReflection = new ReflectionObject($resolver);
|
||||
return count($args) >= count($resolverReflection->getMethod('__invoke')->getParameters()) - 1;
|
||||
}
|
||||
private static function trimName(string $name) : string
|
||||
{
|
||||
if (strpos($name, 'assert') !== 0) {
|
||||
return $name;
|
||||
}
|
||||
$name = substr($name, strlen('assert'));
|
||||
if (strpos($name, 'Not') === 0) {
|
||||
return substr($name, 3);
|
||||
}
|
||||
if (strpos($name, 'IsNot') === 0) {
|
||||
return 'Is' . substr($name, 5);
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
/**
|
||||
* @param Arg[] $args $args
|
||||
*/
|
||||
public static function specifyTypes(TypeSpecifier $typeSpecifier, Scope $scope, string $name, array $args) : SpecifiedTypes
|
||||
{
|
||||
$expression = self::createExpression($scope, $name, $args);
|
||||
if ($expression === null) {
|
||||
return new SpecifiedTypes([], []);
|
||||
}
|
||||
return $typeSpecifier->specifyTypesInCondition($scope, $expression, TypeSpecifierContext::createTruthy());
|
||||
}
|
||||
/**
|
||||
* @param Arg[] $args
|
||||
*/
|
||||
private static function createExpression(Scope $scope, string $name, array $args) : ?Expr
|
||||
{
|
||||
$trimmedName = self::trimName($name);
|
||||
$resolvers = self::getExpressionResolvers();
|
||||
$resolver = $resolvers[$trimmedName];
|
||||
$expression = $resolver($scope, ...$args);
|
||||
if ($expression === null) {
|
||||
return null;
|
||||
}
|
||||
if (strpos($name, 'Not') !== \false) {
|
||||
$expression = new BooleanNot($expression);
|
||||
}
|
||||
return $expression;
|
||||
}
|
||||
/**
|
||||
* @return Closure[]
|
||||
*/
|
||||
private static function getExpressionResolvers() : array
|
||||
{
|
||||
if (self::$resolvers === null) {
|
||||
self::$resolvers = ['InstanceOf' => static function (Scope $scope, Arg $class, Arg $object) : ?Instanceof_ {
|
||||
$classType = $scope->getType($class->value);
|
||||
$classNames = $classType->getConstantStrings();
|
||||
if (count($classNames) !== 1) {
|
||||
return null;
|
||||
}
|
||||
return new Instanceof_($object->value, new Name($classNames[0]->getValue()));
|
||||
}, 'Same' => static function (Scope $scope, Arg $expected, Arg $actual) : Identical {
|
||||
return new Identical($expected->value, $actual->value);
|
||||
}, 'True' => static function (Scope $scope, Arg $actual) : Identical {
|
||||
return new Identical($actual->value, new ConstFetch(new Name('true')));
|
||||
}, 'False' => static function (Scope $scope, Arg $actual) : Identical {
|
||||
return new Identical($actual->value, new ConstFetch(new Name('false')));
|
||||
}, 'Null' => static function (Scope $scope, Arg $actual) : Identical {
|
||||
return new Identical($actual->value, new ConstFetch(new Name('null')));
|
||||
}, 'Empty' => static function (Scope $scope, Arg $actual) : Expr\BinaryOp\BooleanOr {
|
||||
return new Expr\BinaryOp\BooleanOr(new Instanceof_($actual->value, new Name(EmptyIterator::class)), new Expr\BinaryOp\BooleanOr(new Expr\BinaryOp\BooleanAnd(new Instanceof_($actual->value, new Name(Countable::class)), new Identical(new FuncCall(new Name('count'), [new Arg($actual->value)]), new LNumber(0))), new Expr\Empty_($actual->value)));
|
||||
}, 'IsArray' => static function (Scope $scope, Arg $actual) : FuncCall {
|
||||
return new FuncCall(new Name('is_array'), [$actual]);
|
||||
}, 'IsBool' => static function (Scope $scope, Arg $actual) : FuncCall {
|
||||
return new FuncCall(new Name('is_bool'), [$actual]);
|
||||
}, 'IsCallable' => static function (Scope $scope, Arg $actual) : FuncCall {
|
||||
return new FuncCall(new Name('is_callable'), [$actual]);
|
||||
}, 'IsFloat' => static function (Scope $scope, Arg $actual) : FuncCall {
|
||||
return new FuncCall(new Name('is_float'), [$actual]);
|
||||
}, 'IsInt' => static function (Scope $scope, Arg $actual) : FuncCall {
|
||||
return new FuncCall(new Name('is_int'), [$actual]);
|
||||
}, 'IsIterable' => static function (Scope $scope, Arg $actual) : FuncCall {
|
||||
return new FuncCall(new Name('is_iterable'), [$actual]);
|
||||
}, 'IsNumeric' => static function (Scope $scope, Arg $actual) : FuncCall {
|
||||
return new FuncCall(new Name('is_numeric'), [$actual]);
|
||||
}, 'IsObject' => static function (Scope $scope, Arg $actual) : FuncCall {
|
||||
return new FuncCall(new Name('is_object'), [$actual]);
|
||||
}, 'IsResource' => static function (Scope $scope, Arg $actual) : FuncCall {
|
||||
return new FuncCall(new Name('is_resource'), [$actual]);
|
||||
}, 'IsString' => static function (Scope $scope, Arg $actual) : FuncCall {
|
||||
return new FuncCall(new Name('is_string'), [$actual]);
|
||||
}, 'IsScalar' => static function (Scope $scope, Arg $actual) : FuncCall {
|
||||
return new FuncCall(new Name('is_scalar'), [$actual]);
|
||||
}, 'InternalType' => static function (Scope $scope, Arg $type, Arg $value) : ?FuncCall {
|
||||
$typeNames = $scope->getType($type->value)->getConstantStrings();
|
||||
if (count($typeNames) !== 1) {
|
||||
return null;
|
||||
}
|
||||
switch ($typeNames[0]->getValue()) {
|
||||
case 'numeric':
|
||||
$functionName = 'is_numeric';
|
||||
break;
|
||||
case 'integer':
|
||||
case 'int':
|
||||
$functionName = 'is_int';
|
||||
break;
|
||||
case 'double':
|
||||
case 'float':
|
||||
case 'real':
|
||||
$functionName = 'is_float';
|
||||
break;
|
||||
case 'string':
|
||||
$functionName = 'is_string';
|
||||
break;
|
||||
case 'boolean':
|
||||
case 'bool':
|
||||
$functionName = 'is_bool';
|
||||
break;
|
||||
case 'scalar':
|
||||
$functionName = 'is_scalar';
|
||||
break;
|
||||
case 'null':
|
||||
$functionName = 'is_null';
|
||||
break;
|
||||
case 'array':
|
||||
$functionName = 'is_array';
|
||||
break;
|
||||
case 'object':
|
||||
$functionName = 'is_object';
|
||||
break;
|
||||
case 'resource':
|
||||
$functionName = 'is_resource';
|
||||
break;
|
||||
case 'callable':
|
||||
$functionName = 'is_callable';
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return new FuncCall(new Name($functionName), [$value]);
|
||||
}, 'ArrayHasKey' => static function (Scope $scope, Arg $key, Arg $array) : FuncCall {
|
||||
return new FuncCall(new Name('array_key_exists'), [$key, $array]);
|
||||
}, 'ObjectHasAttribute' => static function (Scope $scope, Arg $property, Arg $object) : FuncCall {
|
||||
return new FuncCall(new Name('property_exists'), [$object, $property]);
|
||||
}];
|
||||
}
|
||||
return self::$resolvers;
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\Type\PHPUnit;
|
||||
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Reflection\MethodReflection;
|
||||
use PHPStan\Type\DynamicMethodReturnTypeExtension;
|
||||
use PHPStan\Type\Type;
|
||||
use RectorPrefix202305\PHPUnit\Framework\MockObject\Builder\InvocationMocker;
|
||||
class InvocationMockerDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
|
||||
{
|
||||
public function getClass() : string
|
||||
{
|
||||
return InvocationMocker::class;
|
||||
}
|
||||
public function isMethodSupported(MethodReflection $methodReflection) : bool
|
||||
{
|
||||
return $methodReflection->getName() !== 'getMatcher';
|
||||
}
|
||||
public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope) : Type
|
||||
{
|
||||
return $scope->getType($methodCall->var);
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\Type\PHPUnit;
|
||||
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Reflection\MethodReflection;
|
||||
use PHPStan\Type\DynamicMethodReturnTypeExtension;
|
||||
use PHPStan\Type\Type;
|
||||
use RectorPrefix202305\PHPUnit\Framework\MockObject\MockBuilder;
|
||||
use function in_array;
|
||||
class MockBuilderDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
|
||||
{
|
||||
public function getClass() : string
|
||||
{
|
||||
return MockBuilder::class;
|
||||
}
|
||||
public function isMethodSupported(MethodReflection $methodReflection) : bool
|
||||
{
|
||||
return !in_array($methodReflection->getName(), ['getMock', 'getMockForAbstractClass', 'getMockForTrait'], \true);
|
||||
}
|
||||
public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope) : Type
|
||||
{
|
||||
return $scope->getType($methodCall->var);
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\Type\PHPUnit;
|
||||
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Reflection\MethodReflection;
|
||||
use PHPStan\Type\DynamicMethodReturnTypeExtension;
|
||||
use PHPStan\Type\Generic\GenericObjectType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
use RectorPrefix202305\PHPUnit\Framework\MockObject\Builder\InvocationMocker;
|
||||
use RectorPrefix202305\PHPUnit\Framework\MockObject\MockObject;
|
||||
use function array_filter;
|
||||
use function array_values;
|
||||
use function count;
|
||||
class MockObjectDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
|
||||
{
|
||||
public function getClass() : string
|
||||
{
|
||||
return MockObject::class;
|
||||
}
|
||||
public function isMethodSupported(MethodReflection $methodReflection) : bool
|
||||
{
|
||||
return $methodReflection->getName() === 'expects';
|
||||
}
|
||||
public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope) : Type
|
||||
{
|
||||
$type = $scope->getType($methodCall->var);
|
||||
$mockClasses = array_values(array_filter($type->getObjectClassNames(), static function (string $class) : bool {
|
||||
return $class !== MockObject::class;
|
||||
}));
|
||||
if (count($mockClasses) !== 1) {
|
||||
return new ObjectType(InvocationMocker::class);
|
||||
}
|
||||
return new GenericObjectType(InvocationMocker::class, [new ObjectType($mockClasses[0])]);
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace PHPUnit\Framework\MockObject\Builder;
|
||||
|
||||
use PHPUnit\Framework\MockObject\Stub;
|
||||
|
||||
/**
|
||||
* @template TMockedClass
|
||||
*/
|
||||
class InvocationMocker
|
||||
{
|
||||
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace PHPUnit\Framework\MockObject;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* @template TMockedClass
|
||||
*/
|
||||
class MockBuilder
|
||||
{
|
||||
|
||||
/**
|
||||
* @phpstan-param TestCase $testCase
|
||||
* @phpstan-param class-string<TMockedClass> $type
|
||||
*/
|
||||
public function __construct(TestCase $testCase, $type) {}
|
||||
|
||||
/**
|
||||
* @phpstan-return MockObject&TMockedClass
|
||||
*/
|
||||
public function getMock() {}
|
||||
|
||||
/**
|
||||
* @phpstan-return MockObject&TMockedClass
|
||||
*/
|
||||
public function getMockForAbstractClass() {}
|
||||
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace PHPUnit\Framework\MockObject;
|
||||
|
||||
interface MockObject
|
||||
{
|
||||
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace PHPUnit\Framework\MockObject;
|
||||
|
||||
interface Stub
|
||||
{
|
||||
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace PHPUnit\Framework;
|
||||
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\MockObject\MockBuilder;
|
||||
use PHPUnit\Framework\MockObject\Stub;
|
||||
|
||||
class TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @phpstan-param class-string<T> $originalClassName
|
||||
* @phpstan-return Stub&T
|
||||
*/
|
||||
public function createStub($originalClassName) {}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @phpstan-param class-string<T> $originalClassName
|
||||
* @phpstan-return MockObject&T
|
||||
*/
|
||||
public function createMock($originalClassName) {}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @phpstan-param class-string<T> $className
|
||||
* @phpstan-return MockBuilder<T>
|
||||
*/
|
||||
public function getMockBuilder(string $className) {}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @phpstan-param class-string<T> $originalClassName
|
||||
* @phpstan-return MockObject&T
|
||||
*/
|
||||
public function createConfiguredMock($originalClassName) {}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @phpstan-param class-string<T> $originalClassName
|
||||
* @phpstan-param string[] $methods
|
||||
* @phpstan-return MockObject&T
|
||||
*/
|
||||
public function createPartialMock($originalClassName, array $methods) {}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @phpstan-param class-string<T> $originalClassName
|
||||
* @phpstan-return MockObject&T
|
||||
*/
|
||||
public function createTestProxy($originalClassName) {}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @phpstan-param class-string<T> $originalClassName
|
||||
* @phpstan-param mixed[] $arguments
|
||||
* @phpstan-param string $mockClassName
|
||||
* @phpstan-param bool $callOriginalConstructor
|
||||
* @phpstan-param bool $callOriginalClone
|
||||
* @phpstan-param bool $callAutoload
|
||||
* @phpstan-param string[] $mockedMethods
|
||||
* @phpstan-param bool $cloneArguments
|
||||
* @phpstan-return MockObject&T
|
||||
*/
|
||||
protected function getMockForAbstractClass($originalClassName, array $arguments = [], $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $mockedMethods = [], $cloneArguments = false) {}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @phpstan-param string $wsdlFile
|
||||
* @phpstan-param class-string<T> $originalClassName
|
||||
* @phpstan-param string $mockClassName
|
||||
* @phpstan-param string[] $methods
|
||||
* @phpstan-param bool $callOriginalConstructor
|
||||
* @phpstan-param mixed[] $options
|
||||
* @phpstan-return MockObject&T
|
||||
*/
|
||||
protected function getMockFromWsdl($wsdlFile, $originalClassName = '', $mockClassName = '', array $methods = [], $callOriginalConstructor = true, array $options = []) {}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user