runCompiler(TYPEPHP_ROOT_PATH . '/bin/tpc.php', $temporaryRoot); self::assertSame(0, $result['status'], $result['stderr']); self::assertStringContainsString('TypePHP Compiler (AOT)', $result['stdout']); } finally { $this->removeDirectory($temporaryRoot); } } public function testComposerVendorEntrypointUsesProjectAutoloader(): void { $temporaryRoot = sys_get_temp_dir() . '/typephp-composer-bin-' . bin2hex(random_bytes(6)); $packageRoot = $temporaryRoot . '/vendor/swoole/typephp'; try { $proxy = $this->createComposerEntrypoint($temporaryRoot, $packageRoot); self::assertDirectoryDoesNotExist($packageRoot . '/vendor'); $result = $this->runCompiler($proxy, $temporaryRoot); self::assertSame(0, $result['status'], $result['stderr']); self::assertStringContainsString('TypePHP Compiler (AOT)', $result['stdout']); } finally { $this->removeDirectory($temporaryRoot); } } public function testComposerVendorEntrypointDryCompilesProject(): void { if (!$this->hasPhpxLibrary()) { self::markTestSkipped('A built PHPX library is required for the Zend PHP compiler integration test'); } $temporaryRoot = sys_get_temp_dir() . '/typephp-composer-project-' . bin2hex(random_bytes(6)); $packageRoot = $temporaryRoot . '/vendor/swoole/typephp'; try { $proxy = $this->createComposerEntrypoint($temporaryRoot, $packageRoot); self::assertNotFalse(file_put_contents( $temporaryRoot . '/main.php', "runCompiler( $proxy, $temporaryRoot, ['project.yml', '--dry', '--no-color'], ); self::assertSame(0, $result['status'], $result['stderr']); self::assertStringContainsString('Dry run completed:', $result['stdout']); } finally { $this->removeDirectory($temporaryRoot); } } /** @return array{status: int, stdout: string, stderr: string} */ private function runCompiler( string $entrypoint, string $workingDirectory, array $arguments = ['--version', '--no-color'], ): array { $process = proc_open([PHP_BINARY, $entrypoint, ...$arguments], [ 0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w'], ], $pipes, $workingDirectory, null, ['suppress_errors' => true]); self::assertIsResource($process); fclose($pipes[0]); $stdout = stream_get_contents($pipes[1]); fclose($pipes[1]); $stderr = stream_get_contents($pipes[2]); fclose($pipes[2]); return [ 'status' => proc_close($process), 'stdout' => (string) $stdout, 'stderr' => (string) $stderr, ]; } private function createComposerEntrypoint(string $temporaryRoot, string $packageRoot): string { $this->copyPackageEntrypoint($packageRoot); $proxy = $temporaryRoot . '/vendor/bin/tpc.php'; $proxySource = sprintf( "isDir() ? rmdir($item->getPathname()) : unlink($item->getPathname()); } rmdir($directory); } }