file_provider = new \Psalm\Tests\Internal\Provider\FakeFileProvider(); $config = new TestConfig(); $config->throw_exception = false; $providers = new Providers( $this->file_provider, new \Psalm\Tests\Internal\Provider\ParserInstanceCacheProvider(), null, null, new Provider\FakeFileReferenceCacheProvider(), new \Psalm\Tests\Internal\Provider\ProjectCacheProvider() ); $this->project_analyzer = new ProjectAnalyzer( $config, $providers ); $this->project_analyzer->setPhpVersion('7.3'); } /** * @dataProvider providerTestErrorFix * * @param array> $files * @param array $error_counts * @param array $error_levels * */ public function testErrorFix( array $files, array $error_counts, array $error_levels = [] ): void { $this->project_analyzer->getCodebase()->diff_methods = true; $codebase = $this->project_analyzer->getCodebase(); $config = $codebase->config; foreach ($error_levels as $error_type => $error_level) { $config->setCustomErrorLevel($error_type, $error_level); } $analyzed_files = []; for ($i = 0; $i < count($files); ++$i) { $batch = $files[$i]; foreach ($batch as $file_path => $contents) { $this->file_provider->registerFile($file_path, $contents); if (!isset($analyzed_files[$file_path])) { $codebase->addFilesToAnalyze([$file_path => $file_path]); $analyzed_files[$file_path] = true; } } if ($i === 0) { $codebase->scanFiles(); } else { $codebase->reloadFiles($this->project_analyzer, array_keys($batch)); } $codebase->analyzer->analyzeFiles($this->project_analyzer, 1, false); $expected_count = 0; $data = \Psalm\IssueBuffer::clear(); foreach ($data as $file_issues) { $expected_count += count($file_issues); } $this->assertSame($error_counts[$i], $expected_count); } } /** * @return array>,error_counts:array,error_levels?:array}> */ public function providerTestErrorFix(): array { return [ 'fixMissingColonSyntaxError' => [ 'files' => [ [ getcwd() . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'A.php' => ' ' ' [0, 1, 0], ], 'addReturnTypesToSingleMethod' => [ 'files' => [ [ getcwd() . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'A.php' => 'foo(); } }', ], [ getcwd() . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'A.php' => 'foo(); } }', ], [ getcwd() . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'A.php' => 'foo(); } }', ], ], 'error_counts' => [2, 1, 0], [ 'MissingReturnType' => \Psalm\Config::REPORT_INFO, ], ], 'traitMethodRenameFirstCorrect' => [ 'files' => [ [ getcwd() . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'A.php' => 'bar(); } }', getcwd() . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'T.php' => ' 'bar(); } }', getcwd() . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'T.php' => ' 'bar(); } }', getcwd() . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'T.php' => ' [0, 2, 0], ], 'traitMethodRenameFirstError' => [ 'files' => [ [ getcwd() . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'A.php' => 'bar(); } }', getcwd() . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'T.php' => ' 'bar(); } }', getcwd() . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'T.php' => ' 'bar(); } }', getcwd() . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'T.php' => ' [2, 0, 0], ], 'addSuppressions' => [ 'files' => [ [ getcwd() . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'A.php' => 'bar(); } } }', ], [ getcwd() . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'A.php' => 'bar(); } } }', ], [ getcwd() . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'A.php' => 'bar(); } } }', ], ], 'error_counts' => [2, 1, 0], ], 'fixDefault' => [ 'files' => [ [ getcwd() . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'A.php' => ' ' [1, 0], ], 'changeContent' => [ 'files' => [ [ getcwd() . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'A.php' => ' 'hasMethod($method); }', ], [ getcwd() . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'C.php' => ' 'hasMethod($method); }', ], ], 'error_counts' => [0, 0, 0, 0], ], 'missingConstructorForTwoVars' => [ 'files' => [ [ getcwd() . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'A.php' => ' ' [2, 1], ], 'missingConstructorForInheritedProperties' => [ 'files' => [ [ getcwd() . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'A.php' => ' ' ' [2, 1, 0], ], ]; } }