file_provider = new Provider\FakeFileProvider(); } /** * @return string[] * @psalm-return array */ public static function getAllIssues() { return array_filter( array_map( /** * @param string $file_name * * @return string */ function ($file_name) { return substr($file_name, 0, -4); }, scandir(dirname(__DIR__) . '/src/Psalm/Issue') ), /** * @param string $issue_name * * @return bool */ function ($issue_name) { return !empty($issue_name) && $issue_name !== 'CodeError' && $issue_name !== 'CodeIssue' && $issue_name !== 'FixableCodeIssue'; } ); } /** * @param Config $config * * @return \Psalm\Checker\ProjectChecker */ private function getProjectCheckerWithConfig(Config $config) { return new \Psalm\Checker\ProjectChecker( $config, $this->file_provider, new Provider\FakeParserCacheProvider(), new \Psalm\Provider\NoCache\NoFileStorageCacheProvider(), new \Psalm\Provider\NoCache\NoClassLikeStorageCacheProvider() ); } /** * @return void */ public function testBarebonesConfig() { $this->project_checker = $this->getProjectCheckerWithConfig( Config::loadFromXML( (string)getcwd(), ' ' ) ); $config = $this->project_checker->getConfig(); $this->assertTrue($config->isInProjectDirs(realpath('src/Psalm/Type.php'))); $this->assertFalse($config->isInProjectDirs(realpath('examples/StringChecker.php'))); } /** * @return void */ public function testIgnoreProjectDirectory() { $this->project_checker = $this->getProjectCheckerWithConfig( Config::loadFromXML( dirname(__DIR__), ' ' ) ); $config = $this->project_checker->getConfig(); $this->assertTrue($config->isInProjectDirs(realpath('src/Psalm/Type.php'))); $this->assertFalse($config->isInProjectDirs(realpath('src/Psalm/Checker/FileChecker.php'))); $this->assertFalse($config->isInProjectDirs(realpath('examples/StringChecker.php'))); } /** * @return void */ public function testIssueHandler() { $this->project_checker = $this->getProjectCheckerWithConfig( Config::loadFromXML( dirname(__DIR__), ' ' ) ); $config = $this->project_checker->getConfig(); $this->assertFalse($config->reportIssueInFile('MissingReturnType', realpath('tests/ConfigTest.php'))); $this->assertFalse($config->reportIssueInFile('MissingReturnType', realpath('src/Psalm/Type.php'))); } /** * @return void */ public function testIssueHandlerWithCustomErrorLevels() { $this->project_checker = $this->getProjectCheckerWithConfig( Config::loadFromXML( dirname(__DIR__), ' ' ) ); $config = $this->project_checker->getConfig(); $this->assertSame( 'info', $config->getReportingLevelForFile( 'MissingReturnType', realpath('src/Psalm/Type.php') ) ); $this->assertSame( 'error', $config->getReportingLevelForFile( 'MissingReturnType', realpath('src/Psalm/Checker/FileChecker.php') ) ); } /** * @return void */ public function testAllPossibleIssues() { $all_possible_handlers = implode( ' ', array_map( /** * @param string $issue_name * * @return string */ function ($issue_name) { return '<' . $issue_name . ' errorLevel="suppress" />' . PHP_EOL; }, self::getAllIssues() ) ); $this->project_checker = $this->getProjectCheckerWithConfig( Config::loadFromXML( dirname(__DIR__), ' ' . $all_possible_handlers . ' ' ) ); } /** * @expectedException \Psalm\Exception\ConfigException * @expectedExceptionMessage This element is not expected * * @return void */ public function testImpossibleIssue() { $this->project_checker = $this->getProjectCheckerWithConfig( Config::loadFromXML( dirname(__DIR__), ' ' ) ); } /** * @expectedException \Psalm\Exception\ConfigException * @expectedExceptionMessage Cannot resolve stubfile path * * @return void */ public function testNonexistentStubFile() { $this->project_checker = $this->getProjectCheckerWithConfig( Config::loadFromXML( dirname(__DIR__), ' ' ) ); } /** * @return void */ public function testStubFile() { $this->project_checker = $this->getProjectCheckerWithConfig( TestConfig::loadFromXML( dirname(__DIR__), ' ' ) ); $file_path = getcwd() . '/src/somefile.php'; $this->addFile( $file_path, 'foo(5, "hello"); $c = SystemClass::bar(5, "hello");' ); $this->analyzeFile($file_path, new Context()); } /** * @return void */ public function testNamespacedStubClass() { $this->project_checker = $this->getProjectCheckerWithConfig( TestConfig::loadFromXML( dirname(__DIR__), ' ' ) ); $file_path = getcwd() . '/src/somefile.php'; $this->addFile( $file_path, 'foo(5, "hello"); $c = Foo\SystemClass::bar(5, "hello");' ); $this->analyzeFile($file_path, new Context()); } /** * @return void */ public function testStubFunction() { $this->project_checker = $this->getProjectCheckerWithConfig( TestConfig::loadFromXML( dirname(__DIR__), ' ' ) ); $file_path = getcwd() . '/src/somefile.php'; $this->addFile( $file_path, 'analyzeFile($file_path, new Context()); } /** * @return void */ public function testStubFunctionWithFunctionExists() { $this->project_checker = $this->getProjectCheckerWithConfig( TestConfig::loadFromXML( dirname(__DIR__), ' ' ) ); $file_path = getcwd() . '/src/somefile.php'; $this->addFile( $file_path, 'analyzeFile($file_path, new Context()); } /** * @return void */ public function testNamespacedStubFunctionWithFunctionExists() { $this->project_checker = $this->getProjectCheckerWithConfig( TestConfig::loadFromXML( dirname(__DIR__), ' ' ) ); $file_path = getcwd() . '/src/somefile.php'; $this->addFile( $file_path, 'analyzeFile($file_path, new Context()); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage UndefinedFunction - /src/somefile.php:2 - Function barBar does not exist * * @return void */ public function testNoStubFunction() { $this->project_checker = $this->getProjectCheckerWithConfig( TestConfig::loadFromXML( dirname(__DIR__), ' ' ) ); $file_path = getcwd() . '/src/somefile.php'; $this->addFile( $file_path, 'analyzeFile($file_path, new Context()); } /** * @return void */ public function testNamespacedStubFunction() { $this->project_checker = $this->getProjectCheckerWithConfig( TestConfig::loadFromXML( dirname(__DIR__), ' ' ) ); $file_path = getcwd() . '/src/somefile.php'; $this->addFile( $file_path, 'analyzeFile($file_path, new Context()); } /** * @return void */ public function testConditionalNamespacedStubFunction() { $this->project_checker = $this->getProjectCheckerWithConfig( TestConfig::loadFromXML( dirname(__DIR__), ' ' ) ); $file_path = getcwd() . '/src/somefile.php'; $this->addFile( $file_path, 'analyzeFile($file_path, new Context()); } /** * @return void */ public function testStubFileWithExistingClassDefinition() { $this->project_checker = $this->getProjectCheckerWithConfig( TestConfig::loadFromXML( dirname(__DIR__), ' ' ) ); $file_path = getcwd() . '/src/somefile.php'; $this->addFile( $file_path, 'analyzeFile($file_path, new Context()); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage MissingReturnType * * @return void */ public function testRequireVoidReturnTypeExists() { $this->project_checker = $this->getProjectCheckerWithConfig( TestConfig::loadFromXML( dirname(__DIR__), ' ' ) ); $file_path = getcwd() . '/src/somefile.php'; $this->addFile( $file_path, 'analyzeFile($file_path, new Context()); } /** * @return void */ public function testDoNotRequireVoidReturnTypeExists() { $this->project_checker = $this->getProjectCheckerWithConfig( TestConfig::loadFromXML( dirname(__DIR__), ' ' ) ); $file_path = getcwd() . '/src/somefile.php'; $this->addFile( $file_path, 'analyzeFile($file_path, new Context()); } /** * @return void */ public function testTemplatedFiles() { foreach (['1.xml', '2.xml', '3.xml', '4.xml', '5.xml'] as $file_name) { Config::loadFromXMLFile( realpath(dirname(__DIR__) . '/assets/config_levels/' . $file_name), dirname(__DIR__) ); } } }