mustRun(); } public static function tearDownAfterClass(): void { chdir(self::$previousWorkingDir); self::recursiveRemoveDirectory(self::$tmpDir); parent::tearDownAfterClass(); } public function setUp(): void { @unlink('psalm.xml'); copy(__DIR__ . '/../fixtures/DummyProjectWithErrors/src/FileWithErrors.php', 'src/FileWithErrors.php'); parent::setUp(); } public function testHelpReturnsMessage(): void { $this->assertStringContainsString('Usage:', $this->runPsalm(['--help'])['STDOUT']); } public function testVersion(): void { $this->assertStringStartsWith('Psalm 3', $this->runPsalm(['--version'])['STDOUT']); } public function testInit(): void { $this->assertStringStartsWith('Config file created', $this->runPsalm(['--init'])['STDOUT']); $this->assertFileExists('psalm.xml'); } public function testAlter(): void { $this->runPsalm(['--init']); $this->assertStringContainsString( 'No errors found!', $this->runPsalm(['--alter', '--issues=all'])['STDOUT'] ); $this->assertSame(0, $this->runPsalm([])['CODE']); } public function testPsalter(): void { $this->runPsalm(['--init']); (new Process([$this->psalter, '--alter', '--issues=InvalidReturnType']))->mustRun(); $this->assertSame(0, $this->runPsalm([])['CODE']); } public function testPsalm(): void { $this->runPsalm(['--init']); $result = $this->runPsalm([], true); $this->assertStringContainsString('InvalidReturnType', $result['STDOUT']); $this->assertStringContainsString('InvalidReturnStatement', $result['STDOUT']); $this->assertStringContainsString('2 errors', $result['STDOUT']); $this->assertSame(1, $result['CODE']); } /** * @param array $args * @return array{STDOUT: string, STDERR: string, CODE: int|null} */ private function runPsalm(array $args, bool $shouldFail = false): array { $process = new Process(array_merge([$this->psalm], $args)); if (! $shouldFail) { $process->mustRun(); } else { $process->run(); $this->assertGreaterThan(0, $process->getExitCode()); } return [ 'STDOUT' => $process->getOutput(), 'STDERR' => $process->getErrorOutput(), 'CODE' => $process->getExitCode() ]; } /** from comment by itay at itgoldman dot com at * https://www.php.net/manual/en/function.rmdir.php#117354 */ private static function recursiveRemoveDirectory(string $src): void { $dir = opendir($src); while (false !== ( $file = readdir($dir))) { if (( $file != '.' ) && ( $file != '..' )) { $full = $src . '/' . $file; if (is_dir($full)) { self::recursiveRemoveDirectory($full); } else { unlink($full); } } } closedir($dir); rmdir($src); } }