PageRenderTime 253ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/vendor/phpunit/phpunit/src/Util/PHP.php

https://github.com/tmccormi/openemr
PHP | 410 lines | 301 code | 20 blank | 89 comment | 3 complexity | 9c39386e94ba63e7fd35cf370dcd5d6a MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of PHPUnit.
  4. *
  5. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. use SebastianBergmann\Environment\Runtime;
  11. /**
  12. * Utility methods for PHP sub-processes.
  13. */
  14. abstract class PHPUnit_Util_PHP
  15. {
  16. /**
  17. * @var Runtime
  18. */
  19. protected $runtime;
  20. /**
  21. * @var bool
  22. */
  23. protected $stderrRedirection = false;
  24. /**
  25. * @var string
  26. */
  27. protected $stdin = '';
  28. /**
  29. * @var string
  30. */
  31. protected $args = '';
  32. /**
  33. * @var array
  34. */
  35. protected $env = [];
  36. /**
  37. * @var int
  38. */
  39. protected $timeout = 0;
  40. /**
  41. * Creates internal Runtime instance.
  42. */
  43. public function __construct()
  44. {
  45. $this->runtime = new Runtime();
  46. }
  47. /**
  48. * Defines if should use STDERR redirection or not.
  49. *
  50. * Then $stderrRedirection is TRUE, STDERR is redirected to STDOUT.
  51. *
  52. * @throws PHPUnit_Framework_Exception
  53. *
  54. * @param bool $stderrRedirection
  55. */
  56. public function setUseStderrRedirection($stderrRedirection)
  57. {
  58. if (!is_bool($stderrRedirection)) {
  59. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  60. }
  61. $this->stderrRedirection = $stderrRedirection;
  62. }
  63. /**
  64. * Returns TRUE if uses STDERR redirection or FALSE if not.
  65. *
  66. * @return bool
  67. */
  68. public function useStderrRedirection()
  69. {
  70. return $this->stderrRedirection;
  71. }
  72. /**
  73. * Sets the input string to be sent via STDIN
  74. *
  75. * @param string $stdin
  76. */
  77. public function setStdin($stdin)
  78. {
  79. $this->stdin = (string) $stdin;
  80. }
  81. /**
  82. * Returns the input string to be sent via STDIN
  83. *
  84. * @return string
  85. */
  86. public function getStdin()
  87. {
  88. return $this->stdin;
  89. }
  90. /**
  91. * Sets the string of arguments to pass to the php job
  92. *
  93. * @param string $args
  94. */
  95. public function setArgs($args)
  96. {
  97. $this->args = (string) $args;
  98. }
  99. /**
  100. * Returns the string of arguments to pass to the php job
  101. *
  102. * @retrun string
  103. */
  104. public function getArgs()
  105. {
  106. return $this->args;
  107. }
  108. /**
  109. * Sets the array of environment variables to start the child process with
  110. *
  111. * @param array $env
  112. */
  113. public function setEnv(array $env)
  114. {
  115. $this->env = $env;
  116. }
  117. /**
  118. * Returns the array of environment variables to start the child process with
  119. *
  120. * @return array
  121. */
  122. public function getEnv()
  123. {
  124. return $this->env;
  125. }
  126. /**
  127. * Sets the amount of seconds to wait before timing out
  128. *
  129. * @param int $timeout
  130. */
  131. public function setTimeout($timeout)
  132. {
  133. $this->timeout = (int) $timeout;
  134. }
  135. /**
  136. * Returns the amount of seconds to wait before timing out
  137. *
  138. * @return int
  139. */
  140. public function getTimeout()
  141. {
  142. return $this->timeout;
  143. }
  144. /**
  145. * @return PHPUnit_Util_PHP
  146. */
  147. public static function factory()
  148. {
  149. if (DIRECTORY_SEPARATOR == '\\') {
  150. return new PHPUnit_Util_PHP_Windows;
  151. }
  152. return new PHPUnit_Util_PHP_Default;
  153. }
  154. /**
  155. * Runs a single test in a separate PHP process.
  156. *
  157. * @param string $job
  158. * @param PHPUnit_Framework_Test $test
  159. * @param PHPUnit_Framework_TestResult $result
  160. *
  161. * @throws PHPUnit_Framework_Exception
  162. */
  163. public function runTestJob($job, PHPUnit_Framework_Test $test, PHPUnit_Framework_TestResult $result)
  164. {
  165. $result->startTest($test);
  166. $_result = $this->runJob($job);
  167. $this->processChildResult(
  168. $test,
  169. $result,
  170. $_result['stdout'],
  171. $_result['stderr']
  172. );
  173. }
  174. /**
  175. * Returns the command based into the configurations.
  176. *
  177. * @param array $settings
  178. * @param string|null $file
  179. *
  180. * @return string
  181. */
  182. public function getCommand(array $settings, $file = null)
  183. {
  184. $command = $this->runtime->getBinary();
  185. $command .= $this->settingsToParameters($settings);
  186. if ('phpdbg' === PHP_SAPI) {
  187. $command .= ' -qrr ';
  188. if ($file) {
  189. $command .= '-e ' . escapeshellarg($file);
  190. } else {
  191. $command .= escapeshellarg(__DIR__ . '/PHP/eval-stdin.php');
  192. }
  193. } elseif ($file) {
  194. $command .= ' -f ' . escapeshellarg($file);
  195. }
  196. if ($this->args) {
  197. $command .= ' -- ' . $this->args;
  198. }
  199. if (true === $this->stderrRedirection) {
  200. $command .= ' 2>&1';
  201. }
  202. return $command;
  203. }
  204. /**
  205. * Runs a single job (PHP code) using a separate PHP process.
  206. *
  207. * @param string $job
  208. * @param array $settings
  209. *
  210. * @return array
  211. *
  212. * @throws PHPUnit_Framework_Exception
  213. */
  214. abstract public function runJob($job, array $settings = []);
  215. /**
  216. * @param array $settings
  217. *
  218. * @return string
  219. */
  220. protected function settingsToParameters(array $settings)
  221. {
  222. $buffer = '';
  223. foreach ($settings as $setting) {
  224. $buffer .= ' -d ' . $setting;
  225. }
  226. return $buffer;
  227. }
  228. /**
  229. * Processes the TestResult object from an isolated process.
  230. *
  231. * @param PHPUnit_Framework_Test $test
  232. * @param PHPUnit_Framework_TestResult $result
  233. * @param string $stdout
  234. * @param string $stderr
  235. */
  236. private function processChildResult(PHPUnit_Framework_Test $test, PHPUnit_Framework_TestResult $result, $stdout, $stderr)
  237. {
  238. $time = 0;
  239. if (!empty($stderr)) {
  240. $result->addError(
  241. $test,
  242. new PHPUnit_Framework_Exception(trim($stderr)),
  243. $time
  244. );
  245. } else {
  246. set_error_handler(function ($errno, $errstr, $errfile, $errline) {
  247. throw new ErrorException($errstr, $errno, $errno, $errfile, $errline);
  248. });
  249. try {
  250. if (strpos($stdout, "#!/usr/bin/env php\n") === 0) {
  251. $stdout = substr($stdout, 19);
  252. }
  253. $childResult = unserialize(str_replace("#!/usr/bin/env php\n", '', $stdout));
  254. restore_error_handler();
  255. } catch (ErrorException $e) {
  256. restore_error_handler();
  257. $childResult = false;
  258. $result->addError(
  259. $test,
  260. new PHPUnit_Framework_Exception(trim($stdout), 0, $e),
  261. $time
  262. );
  263. }
  264. if ($childResult !== false) {
  265. if (!empty($childResult['output'])) {
  266. $output = $childResult['output'];
  267. }
  268. $test->setResult($childResult['testResult']);
  269. $test->addToAssertionCount($childResult['numAssertions']);
  270. $childResult = $childResult['result'];
  271. /* @var $childResult PHPUnit_Framework_TestResult */
  272. if ($result->getCollectCodeCoverageInformation()) {
  273. $result->getCodeCoverage()->merge(
  274. $childResult->getCodeCoverage()
  275. );
  276. }
  277. $time = $childResult->time();
  278. $notImplemented = $childResult->notImplemented();
  279. $risky = $childResult->risky();
  280. $skipped = $childResult->skipped();
  281. $errors = $childResult->errors();
  282. $warnings = $childResult->warnings();
  283. $failures = $childResult->failures();
  284. if (!empty($notImplemented)) {
  285. $result->addError(
  286. $test,
  287. $this->getException($notImplemented[0]),
  288. $time
  289. );
  290. } elseif (!empty($risky)) {
  291. $result->addError(
  292. $test,
  293. $this->getException($risky[0]),
  294. $time
  295. );
  296. } elseif (!empty($skipped)) {
  297. $result->addError(
  298. $test,
  299. $this->getException($skipped[0]),
  300. $time
  301. );
  302. } elseif (!empty($errors)) {
  303. $result->addError(
  304. $test,
  305. $this->getException($errors[0]),
  306. $time
  307. );
  308. } elseif (!empty($warnings)) {
  309. $result->addWarning(
  310. $test,
  311. $this->getException($warnings[0]),
  312. $time
  313. );
  314. } elseif (!empty($failures)) {
  315. $result->addFailure(
  316. $test,
  317. $this->getException($failures[0]),
  318. $time
  319. );
  320. }
  321. }
  322. }
  323. $result->endTest($test, $time);
  324. if (!empty($output)) {
  325. print $output;
  326. }
  327. }
  328. /**
  329. * Gets the thrown exception from a PHPUnit_Framework_TestFailure.
  330. *
  331. * @param PHPUnit_Framework_TestFailure $error
  332. *
  333. * @return Exception
  334. *
  335. * @see https://github.com/sebastianbergmann/phpunit/issues/74
  336. */
  337. private function getException(PHPUnit_Framework_TestFailure $error)
  338. {
  339. $exception = $error->thrownException();
  340. if ($exception instanceof __PHP_Incomplete_Class) {
  341. $exceptionArray = [];
  342. foreach ((array) $exception as $key => $value) {
  343. $key = substr($key, strrpos($key, "\0") + 1);
  344. $exceptionArray[$key] = $value;
  345. }
  346. $exception = new PHPUnit_Framework_SyntheticError(
  347. sprintf(
  348. '%s: %s',
  349. $exceptionArray['_PHP_Incomplete_Class_Name'],
  350. $exceptionArray['message']
  351. ),
  352. $exceptionArray['code'],
  353. $exceptionArray['file'],
  354. $exceptionArray['line'],
  355. $exceptionArray['trace']
  356. );
  357. }
  358. return $exception;
  359. }
  360. }