2016-12-29 16:24:10 +01:00
|
|
|
<?php
|
|
|
|
namespace Psalm\Tests;
|
|
|
|
|
2018-11-06 03:57:36 +01:00
|
|
|
use Psalm\Internal\Analyzer\FileAnalyzer;
|
2016-12-29 16:24:10 +01:00
|
|
|
use Psalm\Config;
|
2018-01-21 16:22:04 +01:00
|
|
|
use Psalm\Context;
|
2018-11-12 16:57:05 +01:00
|
|
|
use Psalm\Tests\Internal\Provider;
|
2016-12-29 16:24:10 +01:00
|
|
|
|
2017-07-25 22:11:02 +02:00
|
|
|
class ConfigTest extends TestCase
|
2016-12-29 16:24:10 +01:00
|
|
|
{
|
2017-02-01 01:22:05 +01:00
|
|
|
/** @var TestConfig */
|
|
|
|
protected static $config;
|
|
|
|
|
2018-11-06 03:57:36 +01:00
|
|
|
/** @var \Psalm\Internal\Analyzer\ProjectAnalyzer */
|
2018-11-11 18:01:14 +01:00
|
|
|
protected $project_analyzer;
|
2017-01-02 21:31:18 +01:00
|
|
|
|
2017-02-01 01:22:05 +01:00
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public static function setUpBeforeClass()
|
|
|
|
{
|
|
|
|
self::$config = new TestConfig();
|
2018-04-27 21:00:22 +02:00
|
|
|
|
|
|
|
if (!defined('PSALM_VERSION')) {
|
|
|
|
define('PSALM_VERSION', '2.0.0');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!defined('PHP_PARSER_VERSION')) {
|
|
|
|
define('PHP_PARSER_VERSION', '4.0.0');
|
|
|
|
}
|
2017-02-01 01:22:05 +01:00
|
|
|
}
|
|
|
|
|
2017-01-13 20:07:23 +01:00
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
2016-12-29 16:24:10 +01:00
|
|
|
public function setUp()
|
|
|
|
{
|
2018-11-06 03:57:36 +01:00
|
|
|
FileAnalyzer::clearCache();
|
2017-07-25 22:11:02 +02:00
|
|
|
$this->file_provider = new Provider\FakeFileProvider();
|
2016-12-29 16:24:10 +01:00
|
|
|
}
|
|
|
|
|
2017-01-13 20:07:23 +01:00
|
|
|
/**
|
|
|
|
* @return string[]
|
|
|
|
* @psalm-return array<mixed, string>
|
|
|
|
*/
|
2016-12-30 04:31:52 +01:00
|
|
|
public static function getAllIssues()
|
|
|
|
{
|
|
|
|
return array_filter(
|
|
|
|
array_map(
|
2017-01-13 20:14:24 +01:00
|
|
|
/**
|
|
|
|
* @param string $file_name
|
2017-05-27 02:16:18 +02:00
|
|
|
*
|
2017-01-13 20:14:24 +01:00
|
|
|
* @return string
|
|
|
|
*/
|
2016-12-30 04:31:52 +01:00
|
|
|
function ($file_name) {
|
|
|
|
return substr($file_name, 0, -4);
|
|
|
|
},
|
|
|
|
scandir(dirname(__DIR__) . '/src/Psalm/Issue')
|
|
|
|
),
|
2017-01-13 20:14:24 +01:00
|
|
|
/**
|
|
|
|
* @param string $issue_name
|
2017-05-27 02:16:18 +02:00
|
|
|
*
|
2017-01-13 20:14:24 +01:00
|
|
|
* @return bool
|
|
|
|
*/
|
2016-12-30 04:31:52 +01:00
|
|
|
function ($issue_name) {
|
2018-01-06 01:49:27 +01:00
|
|
|
return !empty($issue_name)
|
2018-03-21 03:36:03 +01:00
|
|
|
&& $issue_name !== 'MethodIssue'
|
2018-05-11 06:07:41 +02:00
|
|
|
&& $issue_name !== 'PropertyIssue'
|
2018-03-21 03:36:03 +01:00
|
|
|
&& $issue_name !== 'ClassIssue'
|
2018-12-05 16:36:42 +01:00
|
|
|
&& $issue_name !== 'CodeIssue'
|
|
|
|
&& $issue_name !== 'PsalmInternalError';
|
2016-12-30 04:31:52 +01:00
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2018-01-21 16:22:04 +01:00
|
|
|
/**
|
|
|
|
* @param Config $config
|
|
|
|
*
|
2018-11-06 03:57:36 +01:00
|
|
|
* @return \Psalm\Internal\Analyzer\ProjectAnalyzer
|
2018-01-21 16:22:04 +01:00
|
|
|
*/
|
2018-11-06 03:57:36 +01:00
|
|
|
private function getProjectAnalyzerWithConfig(Config $config)
|
2018-01-21 16:22:04 +01:00
|
|
|
{
|
2018-11-06 03:57:36 +01:00
|
|
|
return new \Psalm\Internal\Analyzer\ProjectAnalyzer(
|
2018-01-21 16:22:04 +01:00
|
|
|
$config,
|
2018-11-06 03:57:36 +01:00
|
|
|
new \Psalm\Internal\Provider\Providers(
|
2018-09-28 22:18:45 +02:00
|
|
|
$this->file_provider,
|
|
|
|
new Provider\FakeParserCacheProvider()
|
|
|
|
)
|
2018-01-21 16:22:04 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2017-01-13 20:07:23 +01:00
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
2016-12-29 16:24:10 +01:00
|
|
|
public function testBarebonesConfig()
|
|
|
|
{
|
2018-11-11 18:01:14 +01:00
|
|
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
2018-01-21 16:22:04 +01:00
|
|
|
Config::loadFromXML(
|
|
|
|
(string)getcwd(),
|
|
|
|
'<?xml version="1.0"?>
|
|
|
|
<psalm>
|
|
|
|
<projectFiles>
|
|
|
|
<directory name="src" />
|
|
|
|
</projectFiles>
|
|
|
|
</psalm>'
|
|
|
|
)
|
2017-02-01 01:22:05 +01:00
|
|
|
);
|
2016-12-29 16:24:10 +01:00
|
|
|
|
2018-11-11 18:01:14 +01:00
|
|
|
$config = $this->project_analyzer->getConfig();
|
2018-01-21 16:22:04 +01:00
|
|
|
|
2017-01-16 17:41:57 +01:00
|
|
|
$this->assertTrue($config->isInProjectDirs(realpath('src/Psalm/Type.php')));
|
2018-11-06 03:57:36 +01:00
|
|
|
$this->assertFalse($config->isInProjectDirs(realpath('examples/StringAnalyzer.php')));
|
2016-12-29 16:24:10 +01:00
|
|
|
}
|
2016-12-30 00:33:03 +01:00
|
|
|
|
2017-01-13 20:07:23 +01:00
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
2016-12-30 00:33:03 +01:00
|
|
|
public function testIgnoreProjectDirectory()
|
|
|
|
{
|
2018-11-11 18:01:14 +01:00
|
|
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
2018-01-21 16:22:04 +01:00
|
|
|
Config::loadFromXML(
|
|
|
|
dirname(__DIR__),
|
|
|
|
'<?xml version="1.0"?>
|
|
|
|
<psalm>
|
|
|
|
<projectFiles>
|
|
|
|
<directory name="src" />
|
|
|
|
<ignoreFiles>
|
2018-11-06 03:57:36 +01:00
|
|
|
<directory name="src/Psalm/Internal/Analyzer" />
|
2018-01-21 16:22:04 +01:00
|
|
|
</ignoreFiles>
|
|
|
|
</projectFiles>
|
|
|
|
</psalm>'
|
|
|
|
)
|
2017-02-01 01:22:05 +01:00
|
|
|
);
|
2016-12-30 00:33:03 +01:00
|
|
|
|
2018-11-11 18:01:14 +01:00
|
|
|
$config = $this->project_analyzer->getConfig();
|
2018-01-21 16:22:04 +01:00
|
|
|
|
2017-01-16 17:41:57 +01:00
|
|
|
$this->assertTrue($config->isInProjectDirs(realpath('src/Psalm/Type.php')));
|
2018-11-06 03:57:36 +01:00
|
|
|
$this->assertFalse($config->isInProjectDirs(realpath('src/Psalm/Internal/Analyzer/FileAnalyzer.php')));
|
|
|
|
$this->assertFalse($config->isInProjectDirs(realpath('examples/StringAnalyzer.php')));
|
2016-12-30 00:33:03 +01:00
|
|
|
}
|
2016-12-30 02:07:42 +01:00
|
|
|
|
2019-01-06 15:14:35 +01:00
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function testIgnoreSymlinkedProjectDirectory()
|
|
|
|
{
|
|
|
|
@unlink(__DIR__ . '/symlinktest/ignored/b');
|
|
|
|
symlink(__DIR__ . '/symlinktest/a', __DIR__ . '/symlinktest/ignored/b');
|
|
|
|
|
|
|
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
|
|
|
Config::loadFromXML(
|
|
|
|
dirname(__DIR__),
|
|
|
|
'<?xml version="1.0"?>
|
|
|
|
<psalm>
|
|
|
|
<projectFiles>
|
|
|
|
<directory name="tests" />
|
|
|
|
<ignoreFiles>
|
|
|
|
<directory name="tests/symlinktest/ignored" />
|
|
|
|
</ignoreFiles>
|
|
|
|
</projectFiles>
|
|
|
|
</psalm>'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
$config = $this->project_analyzer->getConfig();
|
|
|
|
|
|
|
|
$this->assertTrue($config->isInProjectDirs(realpath('tests/AnnotationTest.php')));
|
|
|
|
$this->assertFalse($config->isInProjectDirs(realpath('tests/symlinktest/a/ignoreme.php')));
|
|
|
|
$this->assertFalse($config->isInProjectDirs(realpath('examples/StringAnalyzer.php')));
|
|
|
|
|
|
|
|
unlink(__DIR__ . '/symlinktest/ignored/b');
|
|
|
|
}
|
|
|
|
|
2018-06-06 02:15:18 +02:00
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function testIgnoreWildcardProjectDirectory()
|
|
|
|
{
|
2018-11-11 18:01:14 +01:00
|
|
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
2018-06-06 02:15:18 +02:00
|
|
|
Config::loadFromXML(
|
|
|
|
dirname(__DIR__),
|
|
|
|
'<?xml version="1.0"?>
|
|
|
|
<psalm>
|
|
|
|
<projectFiles>
|
|
|
|
<directory name="src" />
|
|
|
|
<ignoreFiles>
|
2018-11-06 03:57:36 +01:00
|
|
|
<directory name="src/**/Internal/Analyzer" />
|
2018-06-06 02:15:18 +02:00
|
|
|
</ignoreFiles>
|
|
|
|
</projectFiles>
|
|
|
|
</psalm>'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
2018-11-11 18:01:14 +01:00
|
|
|
$config = $this->project_analyzer->getConfig();
|
2018-06-06 02:15:18 +02:00
|
|
|
|
|
|
|
$this->assertTrue($config->isInProjectDirs(realpath('src/Psalm/Type.php')));
|
2018-11-06 03:57:36 +01:00
|
|
|
$this->assertFalse($config->isInProjectDirs(realpath('src/Psalm/Internal/Analyzer/FileAnalyzer.php')));
|
|
|
|
$this->assertFalse($config->isInProjectDirs(realpath('src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php')));
|
|
|
|
$this->assertFalse($config->isInProjectDirs(realpath('examples/StringAnalyzer.php')));
|
2018-06-06 02:15:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function testIgnoreWildcardFiles()
|
|
|
|
{
|
2018-11-11 18:01:14 +01:00
|
|
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
2018-06-06 02:15:18 +02:00
|
|
|
Config::loadFromXML(
|
|
|
|
dirname(__DIR__),
|
|
|
|
'<?xml version="1.0"?>
|
|
|
|
<psalm>
|
|
|
|
<projectFiles>
|
|
|
|
<directory name="src" />
|
|
|
|
<ignoreFiles>
|
2018-11-06 03:57:36 +01:00
|
|
|
<file name="src/Psalm/Internal/Analyzer/*Analyzer.php" />
|
2018-06-06 02:15:18 +02:00
|
|
|
</ignoreFiles>
|
|
|
|
</projectFiles>
|
|
|
|
</psalm>'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
2018-11-11 18:01:14 +01:00
|
|
|
$config = $this->project_analyzer->getConfig();
|
2018-06-06 02:15:18 +02:00
|
|
|
|
|
|
|
$this->assertTrue($config->isInProjectDirs(realpath('src/Psalm/Type.php')));
|
2018-11-06 03:57:36 +01:00
|
|
|
$this->assertFalse($config->isInProjectDirs(realpath('src/Psalm/Internal/Analyzer/FileAnalyzer.php')));
|
|
|
|
$this->assertTrue($config->isInProjectDirs(realpath('src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php')));
|
|
|
|
$this->assertFalse($config->isInProjectDirs(realpath('examples/StringAnalyzer.php')));
|
2018-06-06 02:15:18 +02:00
|
|
|
}
|
|
|
|
|
2018-07-22 04:34:22 +02:00
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function testIgnoreWildcardFilesInWildcardFolder()
|
|
|
|
{
|
2018-11-11 18:01:14 +01:00
|
|
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
2018-07-22 04:34:22 +02:00
|
|
|
Config::loadFromXML(
|
|
|
|
dirname(__DIR__),
|
|
|
|
'<?xml version="1.0"?>
|
|
|
|
<psalm>
|
|
|
|
<projectFiles>
|
|
|
|
<directory name="src" />
|
|
|
|
<directory name="examples" />
|
|
|
|
<ignoreFiles>
|
2018-11-06 03:57:36 +01:00
|
|
|
<file name="src/Psalm/**/**/*Analyzer.php" />
|
|
|
|
<file name="src/Psalm/**/**/**/*Analyzer.php" />
|
2018-07-22 04:34:22 +02:00
|
|
|
</ignoreFiles>
|
|
|
|
</projectFiles>
|
|
|
|
</psalm>'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
2018-11-11 18:01:14 +01:00
|
|
|
$config = $this->project_analyzer->getConfig();
|
2018-07-22 04:34:22 +02:00
|
|
|
|
|
|
|
$this->assertTrue($config->isInProjectDirs(realpath('src/Psalm/Type.php')));
|
2018-11-13 20:09:37 +01:00
|
|
|
$this->assertTrue($config->isInProjectDirs(realpath('src/Psalm/Internal/Visitor/ReflectorVisitor.php')));
|
2018-11-06 03:57:36 +01:00
|
|
|
$this->assertFalse($config->isInProjectDirs(realpath('src/Psalm/Internal/Analyzer/FileAnalyzer.php')));
|
|
|
|
$this->assertFalse($config->isInProjectDirs(realpath('src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php')));
|
|
|
|
$this->assertTrue($config->isInProjectDirs(realpath('examples/plugins/StringChecker.php')));
|
2018-07-22 04:34:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function testIgnoreWildcardFilesInAllPossibleWildcardFolders()
|
|
|
|
{
|
2018-11-11 18:01:14 +01:00
|
|
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
2018-07-22 04:34:22 +02:00
|
|
|
Config::loadFromXML(
|
|
|
|
dirname(__DIR__),
|
|
|
|
'<?xml version="1.0"?>
|
|
|
|
<psalm>
|
|
|
|
<projectFiles>
|
|
|
|
<directory name="src" />
|
|
|
|
<directory name="examples" />
|
|
|
|
<ignoreFiles>
|
2018-11-06 03:57:36 +01:00
|
|
|
<file name="**/**/**/**/*Analyzer.php" />
|
|
|
|
<file name="**/**/**/**/**/*Analyzer.php" />
|
2018-07-22 04:34:22 +02:00
|
|
|
</ignoreFiles>
|
|
|
|
</projectFiles>
|
|
|
|
</psalm>'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
2018-11-11 18:01:14 +01:00
|
|
|
$config = $this->project_analyzer->getConfig();
|
2018-07-22 04:34:22 +02:00
|
|
|
|
|
|
|
$this->assertTrue($config->isInProjectDirs(realpath('src/Psalm/Type.php')));
|
2018-11-13 20:09:37 +01:00
|
|
|
$this->assertTrue($config->isInProjectDirs(realpath('src/Psalm/Internal/Visitor/ReflectorVisitor.php')));
|
2018-11-06 03:57:36 +01:00
|
|
|
$this->assertFalse($config->isInProjectDirs(realpath('src/Psalm/Internal/Analyzer/FileAnalyzer.php')));
|
|
|
|
$this->assertFalse($config->isInProjectDirs(realpath('src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php')));
|
|
|
|
$this->assertFalse($config->isInProjectDirs(realpath('examples/StringAnalyzer.php')));
|
2018-07-22 04:34:22 +02:00
|
|
|
}
|
|
|
|
|
2017-01-13 20:07:23 +01:00
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
2016-12-30 02:07:42 +01:00
|
|
|
public function testIssueHandler()
|
|
|
|
{
|
2018-11-11 18:01:14 +01:00
|
|
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
2018-01-21 16:22:04 +01:00
|
|
|
Config::loadFromXML(
|
|
|
|
dirname(__DIR__),
|
|
|
|
'<?xml version="1.0"?>
|
|
|
|
<psalm>
|
|
|
|
<projectFiles>
|
|
|
|
<directory name="src" />
|
|
|
|
<directory name="tests" />
|
|
|
|
</projectFiles>
|
|
|
|
|
|
|
|
<issueHandlers>
|
|
|
|
<MissingReturnType errorLevel="suppress" />
|
|
|
|
</issueHandlers>
|
|
|
|
</psalm>'
|
|
|
|
)
|
2017-02-01 01:22:05 +01:00
|
|
|
);
|
2016-12-30 02:07:42 +01:00
|
|
|
|
2018-11-11 18:01:14 +01:00
|
|
|
$config = $this->project_analyzer->getConfig();
|
2018-01-21 16:22:04 +01:00
|
|
|
|
2017-03-24 23:34:46 +01:00
|
|
|
$this->assertFalse($config->reportIssueInFile('MissingReturnType', realpath('tests/ConfigTest.php')));
|
|
|
|
$this->assertFalse($config->reportIssueInFile('MissingReturnType', realpath('src/Psalm/Type.php')));
|
2016-12-30 02:07:42 +01:00
|
|
|
}
|
|
|
|
|
2017-01-13 20:07:23 +01:00
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
2016-12-30 02:07:42 +01:00
|
|
|
public function testIssueHandlerWithCustomErrorLevels()
|
|
|
|
{
|
2018-11-11 18:01:14 +01:00
|
|
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
2018-01-21 16:22:04 +01:00
|
|
|
Config::loadFromXML(
|
|
|
|
dirname(__DIR__),
|
|
|
|
'<?xml version="1.0"?>
|
|
|
|
<psalm>
|
|
|
|
<projectFiles>
|
|
|
|
<directory name="src" />
|
|
|
|
<directory name="tests" />
|
|
|
|
</projectFiles>
|
|
|
|
|
|
|
|
<issueHandlers>
|
|
|
|
<MissingReturnType errorLevel="info">
|
|
|
|
<errorLevel type="suppress">
|
|
|
|
<directory name="tests" />
|
|
|
|
</errorLevel>
|
|
|
|
<errorLevel type="error">
|
2018-11-06 03:57:36 +01:00
|
|
|
<directory name="src/Psalm/Internal/Analyzer" />
|
2018-01-21 16:22:04 +01:00
|
|
|
</errorLevel>
|
|
|
|
</MissingReturnType>
|
2018-03-21 03:36:03 +01:00
|
|
|
<UndefinedClass>
|
|
|
|
<errorLevel type="suppress">
|
|
|
|
<referencedClass name="Psalm\Badger" />
|
|
|
|
</errorLevel>
|
|
|
|
</UndefinedClass>
|
|
|
|
<UndefinedMethod>
|
|
|
|
<errorLevel type="suppress">
|
|
|
|
<referencedMethod name="Psalm\Bodger::find1" />
|
2018-11-29 02:09:20 +01:00
|
|
|
<referencedMethod name="*::find2" />
|
2018-03-21 03:36:03 +01:00
|
|
|
</errorLevel>
|
|
|
|
</UndefinedMethod>
|
2018-11-30 05:19:22 +01:00
|
|
|
<UndefinedFunction>
|
|
|
|
<errorLevel type="suppress">
|
|
|
|
<referencedFunction name="fooBar" />
|
|
|
|
</errorLevel>
|
|
|
|
</UndefinedFunction>
|
2018-05-11 06:07:41 +02:00
|
|
|
<UndefinedPropertyFetch>
|
|
|
|
<errorLevel type="suppress">
|
|
|
|
<referencedProperty name="Psalm\Bodger::$find3" />
|
|
|
|
</errorLevel>
|
|
|
|
</UndefinedPropertyFetch>
|
2018-01-21 16:22:04 +01:00
|
|
|
</issueHandlers>
|
|
|
|
</psalm>'
|
|
|
|
)
|
2017-02-01 01:22:05 +01:00
|
|
|
);
|
2016-12-30 02:07:42 +01:00
|
|
|
|
2018-11-11 18:01:14 +01:00
|
|
|
$config = $this->project_analyzer->getConfig();
|
2018-01-21 16:22:04 +01:00
|
|
|
|
2017-04-25 05:45:02 +02:00
|
|
|
$this->assertSame(
|
|
|
|
'info',
|
|
|
|
$config->getReportingLevelForFile(
|
|
|
|
'MissingReturnType',
|
|
|
|
realpath('src/Psalm/Type.php')
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertSame(
|
|
|
|
'error',
|
|
|
|
$config->getReportingLevelForFile(
|
|
|
|
'MissingReturnType',
|
2018-11-06 03:57:36 +01:00
|
|
|
realpath('src/Psalm/Internal/Analyzer/FileAnalyzer.php')
|
2017-04-25 05:45:02 +02:00
|
|
|
)
|
|
|
|
);
|
2018-03-21 03:36:03 +01:00
|
|
|
|
|
|
|
$this->assertSame(
|
|
|
|
'suppress',
|
|
|
|
$config->getReportingLevelForClass(
|
|
|
|
'UndefinedClass',
|
|
|
|
'Psalm\Badger'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertSame(
|
|
|
|
'error',
|
|
|
|
$config->getReportingLevelForClass(
|
|
|
|
'UndefinedClass',
|
|
|
|
'Psalm\Bodger'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertSame(
|
|
|
|
'suppress',
|
|
|
|
$config->getReportingLevelForMethod(
|
|
|
|
'UndefinedMethod',
|
|
|
|
'Psalm\Bodger::find1'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
2018-11-29 02:09:20 +01:00
|
|
|
$this->assertSame(
|
|
|
|
'suppress',
|
|
|
|
$config->getReportingLevelForMethod(
|
|
|
|
'UndefinedMethod',
|
|
|
|
'Psalm\Bodger::find2'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertSame(
|
|
|
|
'suppress',
|
|
|
|
$config->getReportingLevelForMethod(
|
|
|
|
'UndefinedMethod',
|
|
|
|
'Psalm\Badger::find2'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
2018-03-21 03:36:03 +01:00
|
|
|
$this->assertSame(
|
|
|
|
'error',
|
2018-05-11 06:07:41 +02:00
|
|
|
$config->getReportingLevelForProperty(
|
|
|
|
'UndefinedMethod',
|
|
|
|
'Psalm\Bodger::$find3'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertSame(
|
|
|
|
'error',
|
|
|
|
$config->getReportingLevelForProperty(
|
2018-03-21 03:36:03 +01:00
|
|
|
'UndefinedMethod',
|
2018-05-11 06:07:41 +02:00
|
|
|
'Psalm\Bodger::$find4'
|
2018-03-21 03:36:03 +01:00
|
|
|
)
|
|
|
|
);
|
2018-11-30 05:19:22 +01:00
|
|
|
|
|
|
|
$this->assertSame(
|
|
|
|
'suppress',
|
|
|
|
$config->getReportingLevelForMethod(
|
|
|
|
'UndefinedFunction',
|
|
|
|
'fooBar'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertSame(
|
|
|
|
'suppress',
|
|
|
|
$config->getReportingLevelForMethod(
|
|
|
|
'UndefinedFunction',
|
|
|
|
'foobar'
|
|
|
|
)
|
|
|
|
);
|
2016-12-30 02:07:42 +01:00
|
|
|
}
|
2016-12-30 04:31:52 +01:00
|
|
|
|
2017-01-13 20:07:23 +01:00
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
2016-12-30 04:31:52 +01:00
|
|
|
public function testAllPossibleIssues()
|
|
|
|
{
|
|
|
|
$all_possible_handlers = implode(
|
|
|
|
' ',
|
|
|
|
array_map(
|
2017-01-13 20:14:24 +01:00
|
|
|
/**
|
|
|
|
* @param string $issue_name
|
2017-05-27 02:16:18 +02:00
|
|
|
*
|
2017-01-13 20:14:24 +01:00
|
|
|
* @return string
|
|
|
|
*/
|
2016-12-30 04:31:52 +01:00
|
|
|
function ($issue_name) {
|
2019-01-07 14:38:56 +01:00
|
|
|
if ($issue_name === 'ParseError' || $issue_name === 'PluginIssue') {
|
2018-09-29 06:15:39 +02:00
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
2018-04-13 01:42:24 +02:00
|
|
|
return '<' . $issue_name . ' errorLevel="suppress" />' . "\n";
|
2016-12-30 04:31:52 +01:00
|
|
|
},
|
|
|
|
self::getAllIssues()
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
2018-11-11 18:01:14 +01:00
|
|
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
2018-01-21 16:22:04 +01:00
|
|
|
Config::loadFromXML(
|
|
|
|
dirname(__DIR__),
|
|
|
|
'<?xml version="1.0"?>
|
|
|
|
<psalm>
|
|
|
|
<projectFiles>
|
|
|
|
<directory name="src" />
|
|
|
|
</projectFiles>
|
|
|
|
|
|
|
|
<issueHandlers>
|
|
|
|
' . $all_possible_handlers . '
|
|
|
|
</issueHandlers>
|
|
|
|
</psalm>'
|
|
|
|
)
|
2017-02-01 01:22:05 +01:00
|
|
|
);
|
2016-12-30 04:31:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-01-13 20:07:23 +01:00
|
|
|
* @expectedException \Psalm\Exception\ConfigException
|
2016-12-30 04:31:52 +01:00
|
|
|
* @expectedExceptionMessage This element is not expected
|
2017-05-27 02:16:18 +02:00
|
|
|
*
|
2017-01-13 20:07:23 +01:00
|
|
|
* @return void
|
2016-12-30 04:31:52 +01:00
|
|
|
*/
|
|
|
|
public function testImpossibleIssue()
|
|
|
|
{
|
2018-11-11 18:01:14 +01:00
|
|
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
2018-01-21 16:22:04 +01:00
|
|
|
Config::loadFromXML(
|
|
|
|
dirname(__DIR__),
|
|
|
|
'<?xml version="1.0"?>
|
|
|
|
<psalm>
|
|
|
|
<projectFiles>
|
|
|
|
<directory name="src" />
|
|
|
|
</projectFiles>
|
|
|
|
|
|
|
|
<issueHandlers>
|
|
|
|
<ImpossibleIssue errorLevel="suppress" />
|
|
|
|
</issueHandlers>
|
|
|
|
</psalm>'
|
|
|
|
)
|
2017-02-01 01:22:05 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2017-02-01 16:13:37 +01:00
|
|
|
/**
|
|
|
|
* @expectedException \Psalm\Exception\CodeException
|
|
|
|
* @expectedExceptionMessage MissingReturnType
|
2017-05-27 02:16:18 +02:00
|
|
|
*
|
2017-02-01 16:13:37 +01:00
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function testRequireVoidReturnTypeExists()
|
|
|
|
{
|
2018-11-11 18:01:14 +01:00
|
|
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
2017-02-01 16:13:37 +01:00
|
|
|
TestConfig::loadFromXML(
|
2017-05-04 20:25:58 +02:00
|
|
|
dirname(__DIR__),
|
2017-02-01 16:13:37 +01:00
|
|
|
'<?xml version="1.0"?>
|
|
|
|
<psalm
|
|
|
|
requireVoidReturnType="true">
|
|
|
|
<projectFiles>
|
|
|
|
<directory name="src" />
|
|
|
|
</projectFiles>
|
|
|
|
</psalm>'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
2018-01-21 16:22:04 +01:00
|
|
|
$file_path = getcwd() . '/src/somefile.php';
|
|
|
|
|
2017-07-25 22:11:02 +02:00
|
|
|
$this->addFile(
|
2018-01-21 16:22:04 +01:00
|
|
|
$file_path,
|
2017-07-25 22:11:02 +02:00
|
|
|
'<?php
|
|
|
|
function foo() {}'
|
|
|
|
);
|
2017-02-01 16:13:37 +01:00
|
|
|
|
2018-01-21 16:22:04 +01:00
|
|
|
$this->analyzeFile($file_path, new Context());
|
2017-02-01 16:13:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function testDoNotRequireVoidReturnTypeExists()
|
|
|
|
{
|
2018-11-11 18:01:14 +01:00
|
|
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
2017-02-01 16:13:37 +01:00
|
|
|
TestConfig::loadFromXML(
|
2017-05-04 20:25:58 +02:00
|
|
|
dirname(__DIR__),
|
2017-02-01 16:13:37 +01:00
|
|
|
'<?xml version="1.0"?>
|
|
|
|
<psalm
|
|
|
|
requireVoidReturnType="false">
|
|
|
|
<projectFiles>
|
|
|
|
<directory name="src" />
|
|
|
|
</projectFiles>
|
|
|
|
</psalm>'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
2018-01-21 16:22:04 +01:00
|
|
|
$file_path = getcwd() . '/src/somefile.php';
|
|
|
|
|
2017-07-25 22:11:02 +02:00
|
|
|
$this->addFile(
|
2018-01-21 16:22:04 +01:00
|
|
|
$file_path,
|
2017-07-25 22:11:02 +02:00
|
|
|
'<?php
|
|
|
|
function foo() {}'
|
|
|
|
);
|
2017-02-01 16:13:37 +01:00
|
|
|
|
2018-01-21 16:22:04 +01:00
|
|
|
$this->analyzeFile($file_path, new Context());
|
2017-02-01 16:13:37 +01:00
|
|
|
}
|
2017-02-13 05:59:33 +01:00
|
|
|
|
2018-04-28 19:05:43 +02:00
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function testMethodCallMemoize()
|
|
|
|
{
|
2018-11-11 18:01:14 +01:00
|
|
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
2018-04-28 19:05:43 +02:00
|
|
|
TestConfig::loadFromXML(
|
|
|
|
dirname(__DIR__),
|
|
|
|
'<?xml version="1.0"?>
|
|
|
|
<psalm memoizeMethodCallResults="true">
|
|
|
|
<projectFiles>
|
|
|
|
<directory name="src" />
|
|
|
|
</projectFiles>
|
|
|
|
</psalm>'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
$file_path = getcwd() . '/src/somefile.php';
|
|
|
|
|
|
|
|
$this->addFile(
|
|
|
|
$file_path,
|
|
|
|
'<?php
|
|
|
|
class A {
|
|
|
|
function getFoo() : ?Foo {
|
|
|
|
return rand(0, 1) ? new Foo : null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
class Foo {
|
2018-07-03 18:45:29 +02:00
|
|
|
function getBar() : ?Bar {
|
|
|
|
return rand(0, 1) ? new Bar : null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
class Bar {
|
|
|
|
public function bat() : void {}
|
2018-04-28 19:05:43 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
$a = new A();
|
|
|
|
|
|
|
|
if ($a->getFoo()) {
|
2018-07-03 18:45:29 +02:00
|
|
|
if ($a->getFoo()->getBar()) {
|
|
|
|
$a->getFoo()->getBar()->bat();
|
|
|
|
}
|
2018-04-28 19:05:43 +02:00
|
|
|
}'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->analyzeFile($file_path, new Context());
|
|
|
|
}
|
|
|
|
|
2019-01-13 15:49:34 +01:00
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function testThing()
|
|
|
|
{
|
|
|
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
|
|
|
TestConfig::loadFromXML(
|
|
|
|
dirname(__DIR__),
|
|
|
|
'<?xml version="1.0"?>
|
|
|
|
<psalm>
|
|
|
|
<projectFiles>
|
|
|
|
<directory name="src" />
|
|
|
|
</projectFiles>
|
|
|
|
<mockClasses>
|
|
|
|
<class name="MyMockClass" />
|
|
|
|
</mockClasses>
|
|
|
|
</psalm>'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
$file_path = getcwd() . '/src/somefile.php';
|
|
|
|
|
|
|
|
$this->addFile(
|
|
|
|
$file_path,
|
|
|
|
'<?php
|
|
|
|
class MyMockClass {}
|
|
|
|
|
|
|
|
$a = new MyMockClass();
|
|
|
|
$a->foo($b = 5);
|
|
|
|
echo $b;'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->analyzeFile($file_path, new Context());
|
|
|
|
}
|
|
|
|
|
2018-07-13 05:26:08 +02:00
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function testExitFunctions()
|
|
|
|
{
|
2018-11-11 18:01:14 +01:00
|
|
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
2018-07-13 05:26:08 +02:00
|
|
|
TestConfig::loadFromXML(
|
|
|
|
dirname(__DIR__),
|
|
|
|
'<?xml version="1.0"?>
|
|
|
|
<psalm>
|
|
|
|
<exitFunctions>
|
|
|
|
<function name="leave" />
|
|
|
|
<function name="Foo\namespacedLeave" />
|
|
|
|
<function name="Foo\Bar::staticLeave" />
|
|
|
|
</exitFunctions>
|
|
|
|
</psalm>'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
$file_path = getcwd() . '/src/somefile.php';
|
|
|
|
|
|
|
|
$this->addFile(
|
|
|
|
$file_path,
|
|
|
|
'<?php
|
|
|
|
namespace {
|
|
|
|
function leave() : void {
|
|
|
|
exit();
|
|
|
|
}
|
|
|
|
|
|
|
|
function mightLeave() : string {
|
|
|
|
if (rand(0, 1)) {
|
|
|
|
leave();
|
|
|
|
} else {
|
|
|
|
return "here";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function mightLeaveWithNamespacedFunction() : string {
|
|
|
|
if (rand(0, 1)) {
|
|
|
|
\Foo\namespacedLeave();
|
|
|
|
} else {
|
|
|
|
return "here";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function mightLeaveWithStaticMethod() : string {
|
|
|
|
if (rand(0, 1)) {
|
|
|
|
Foo\Bar::staticLeave();
|
|
|
|
} else {
|
|
|
|
return "here";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace Foo {
|
|
|
|
function namespacedLeave() : void {
|
|
|
|
exit();
|
|
|
|
}
|
|
|
|
|
|
|
|
class Bar {
|
|
|
|
public static function staticLeave() : void {
|
|
|
|
exit();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->analyzeFile($file_path, new Context());
|
|
|
|
}
|
|
|
|
|
2018-09-18 22:42:51 +02:00
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function testAllowedEchoFunction()
|
|
|
|
{
|
2018-11-11 18:01:14 +01:00
|
|
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
2018-09-18 22:42:51 +02:00
|
|
|
TestConfig::loadFromXML(
|
|
|
|
dirname(__DIR__),
|
|
|
|
'<?xml version="1.0"?>
|
|
|
|
<psalm></psalm>'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
$file_path = getcwd() . '/src/somefile.php';
|
|
|
|
|
|
|
|
$this->addFile(
|
|
|
|
$file_path,
|
|
|
|
'<?php
|
|
|
|
echo "hello";'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->analyzeFile($file_path, new Context());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @expectedException \Psalm\Exception\CodeException
|
|
|
|
* @expectedExceptionMessage ForbiddenCode
|
|
|
|
* @return void
|
|
|
|
*/
|
2018-09-18 23:08:32 +02:00
|
|
|
public function testForbiddenEchoFunctionViaFunctions()
|
2018-09-18 22:42:51 +02:00
|
|
|
{
|
2018-11-11 18:01:14 +01:00
|
|
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
2018-09-18 22:42:51 +02:00
|
|
|
TestConfig::loadFromXML(
|
|
|
|
dirname(__DIR__),
|
|
|
|
'<?xml version="1.0"?>
|
|
|
|
<psalm>
|
|
|
|
<forbiddenFunctions>
|
|
|
|
<function name="echo" />
|
|
|
|
</forbiddenFunctions>
|
|
|
|
</psalm>'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
$file_path = getcwd() . '/src/somefile.php';
|
2018-09-18 23:08:32 +02:00
|
|
|
|
|
|
|
$this->addFile(
|
|
|
|
$file_path,
|
|
|
|
'<?php
|
|
|
|
echo "hello";'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->analyzeFile($file_path, new Context());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @expectedException \Psalm\Exception\CodeException
|
|
|
|
* @expectedExceptionMessage ForbiddenEcho
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function testForbiddenEchoFunctionViaFlag()
|
|
|
|
{
|
2018-11-11 18:01:14 +01:00
|
|
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
2018-09-18 23:08:32 +02:00
|
|
|
TestConfig::loadFromXML(
|
|
|
|
dirname(__DIR__),
|
|
|
|
'<?xml version="1.0"?>
|
|
|
|
<psalm forbidEcho="true"></psalm>'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
$file_path = getcwd() . '/src/somefile.php';
|
2018-09-18 22:42:51 +02:00
|
|
|
|
|
|
|
$this->addFile(
|
|
|
|
$file_path,
|
|
|
|
'<?php
|
|
|
|
echo "hello";'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->analyzeFile($file_path, new Context());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function testAllowedVarExportFunction()
|
|
|
|
{
|
2018-11-11 18:01:14 +01:00
|
|
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
2018-09-18 22:42:51 +02:00
|
|
|
TestConfig::loadFromXML(
|
|
|
|
dirname(__DIR__),
|
|
|
|
'<?xml version="1.0"?>
|
|
|
|
<psalm></psalm>'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
$file_path = getcwd() . '/src/somefile.php';
|
|
|
|
|
|
|
|
$this->addFile(
|
|
|
|
$file_path,
|
|
|
|
'<?php
|
|
|
|
$a = [1, 2, 3];
|
|
|
|
var_export($a);'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->analyzeFile($file_path, new Context());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @expectedException \Psalm\Exception\CodeException
|
|
|
|
* @expectedExceptionMessage ForbiddenCode
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function testForbiddenVarExportFunction()
|
|
|
|
{
|
2018-11-11 18:01:14 +01:00
|
|
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
2018-09-18 22:42:51 +02:00
|
|
|
TestConfig::loadFromXML(
|
|
|
|
dirname(__DIR__),
|
|
|
|
'<?xml version="1.0"?>
|
|
|
|
<psalm>
|
|
|
|
<forbiddenFunctions>
|
|
|
|
<function name="var_export" />
|
|
|
|
</forbiddenFunctions>
|
|
|
|
</psalm>'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
$file_path = getcwd() . '/src/somefile.php';
|
|
|
|
|
|
|
|
$this->addFile(
|
|
|
|
$file_path,
|
|
|
|
'<?php
|
|
|
|
$a = [1, 2, 3];
|
|
|
|
var_export($a);'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->analyzeFile($file_path, new Context());
|
|
|
|
}
|
|
|
|
|
2018-09-21 17:35:51 +02:00
|
|
|
/**
|
|
|
|
* @expectedException \Psalm\Exception\CodeException
|
|
|
|
* @expectedExceptionMessage InvalidCatch
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function testValidThrowInvalidCatch()
|
|
|
|
{
|
2018-11-11 18:01:14 +01:00
|
|
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
2018-09-21 17:35:51 +02:00
|
|
|
TestConfig::loadFromXML(
|
|
|
|
dirname(__DIR__),
|
|
|
|
'<?xml version="1.0"?>
|
|
|
|
<psalm>
|
|
|
|
<issueHandlers>
|
|
|
|
<InvalidThrow>
|
|
|
|
<errorLevel type="suppress">
|
|
|
|
<referencedClass name="I" />
|
|
|
|
</errorLevel>
|
|
|
|
</InvalidThrow>
|
|
|
|
</issueHandlers>
|
|
|
|
</psalm>'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
$file_path = getcwd() . '/src/somefile.php';
|
|
|
|
|
|
|
|
$this->addFile(
|
|
|
|
$file_path,
|
|
|
|
'<?php
|
|
|
|
interface I {}
|
|
|
|
|
|
|
|
class E extends Exception implements I {}
|
|
|
|
|
|
|
|
function foo() : void {
|
|
|
|
throw new E();
|
|
|
|
}
|
|
|
|
|
|
|
|
function handleThrow(I $e) : void {
|
|
|
|
echo "about to throw";
|
|
|
|
throw $e;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
foo();
|
|
|
|
} catch (I $e) {
|
|
|
|
handleThrow($e);
|
|
|
|
}'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->analyzeFile($file_path, new Context());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @expectedException \Psalm\Exception\CodeException
|
|
|
|
* @expectedExceptionMessage InvalidThrow
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function testInvalidThrowValidCatch()
|
|
|
|
{
|
2018-11-11 18:01:14 +01:00
|
|
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
2018-09-21 17:35:51 +02:00
|
|
|
TestConfig::loadFromXML(
|
|
|
|
dirname(__DIR__),
|
|
|
|
'<?xml version="1.0"?>
|
|
|
|
<psalm>
|
|
|
|
<issueHandlers>
|
|
|
|
<InvalidCatch>
|
|
|
|
<errorLevel type="suppress">
|
|
|
|
<referencedClass name="I" />
|
|
|
|
</errorLevel>
|
|
|
|
</InvalidCatch>
|
|
|
|
</issueHandlers>
|
|
|
|
</psalm>'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
$file_path = getcwd() . '/src/somefile.php';
|
|
|
|
|
|
|
|
$this->addFile(
|
|
|
|
$file_path,
|
|
|
|
'<?php
|
|
|
|
interface I {}
|
|
|
|
|
|
|
|
class E extends Exception implements I {}
|
|
|
|
|
|
|
|
function foo() : void {
|
|
|
|
throw new E();
|
|
|
|
}
|
|
|
|
|
|
|
|
function handleThrow(I $e) : void {
|
|
|
|
echo "about to throw";
|
|
|
|
throw $e;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
foo();
|
|
|
|
} catch (I $e) {
|
|
|
|
handleThrow($e);
|
|
|
|
}'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->analyzeFile($file_path, new Context());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function testValidThrowValidCatch()
|
|
|
|
{
|
2018-11-11 18:01:14 +01:00
|
|
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
2018-09-21 17:35:51 +02:00
|
|
|
TestConfig::loadFromXML(
|
|
|
|
dirname(__DIR__),
|
|
|
|
'<?xml version="1.0"?>
|
|
|
|
<psalm>
|
|
|
|
<issueHandlers>
|
|
|
|
<InvalidCatch>
|
|
|
|
<errorLevel type="suppress">
|
|
|
|
<referencedClass name="I" />
|
|
|
|
</errorLevel>
|
|
|
|
</InvalidCatch>
|
|
|
|
<InvalidThrow>
|
|
|
|
<errorLevel type="suppress">
|
|
|
|
<referencedClass name="I" />
|
|
|
|
</errorLevel>
|
|
|
|
</InvalidThrow>
|
|
|
|
</issueHandlers>
|
|
|
|
</psalm>'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
$file_path = getcwd() . '/src/somefile.php';
|
|
|
|
|
|
|
|
$this->addFile(
|
|
|
|
$file_path,
|
|
|
|
'<?php
|
|
|
|
interface I {}
|
|
|
|
|
|
|
|
class E extends Exception implements I {}
|
|
|
|
|
|
|
|
function foo() : void {
|
|
|
|
throw new E();
|
|
|
|
}
|
|
|
|
|
|
|
|
function handleThrow(I $e) : void {
|
|
|
|
echo "about to throw";
|
|
|
|
throw $e;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
foo();
|
|
|
|
} catch (I $e) {
|
|
|
|
handleThrow($e);
|
|
|
|
}'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->analyzeFile($file_path, new Context());
|
|
|
|
}
|
|
|
|
|
2017-02-13 05:59:33 +01:00
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function testTemplatedFiles()
|
|
|
|
{
|
2018-04-19 07:03:28 +02:00
|
|
|
foreach (['1.xml', '2.xml', '3.xml', '4.xml', '5.xml', '6.xml', '7.xml', '8.xml'] as $file_name) {
|
2017-05-04 20:25:58 +02:00
|
|
|
Config::loadFromXMLFile(
|
|
|
|
realpath(dirname(__DIR__) . '/assets/config_levels/' . $file_name),
|
|
|
|
dirname(__DIR__)
|
|
|
|
);
|
2017-02-13 05:59:33 +01:00
|
|
|
}
|
|
|
|
}
|
2016-12-29 16:24:10 +01:00
|
|
|
}
|