Просмотр файла vendor/symfony/console/Tester/TesterTrait.php

Размер файла: 5.66Kb
  1. <?php
  2.  
  3. /*
  4. * This file is part of the Symfony package.
  5. *
  6. * (c) Fabien Potencier <fabien@symfony.com>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11.  
  12. namespace Symfony\Component\Console\Tester;
  13.  
  14. use PHPUnit\Framework\Assert;
  15. use Symfony\Component\Console\Input\InputInterface;
  16. use Symfony\Component\Console\Output\ConsoleOutput;
  17. use Symfony\Component\Console\Output\OutputInterface;
  18. use Symfony\Component\Console\Output\StreamOutput;
  19. use Symfony\Component\Console\Tester\Constraint\CommandIsSuccessful;
  20.  
  21. /**
  22. * @author Amrouche Hamza <hamza.simperfit@gmail.com>
  23. */
  24. trait TesterTrait
  25. {
  26. private $output;
  27. private array $inputs = [];
  28. private bool $captureStreamsIndependently = false;
  29. private $input;
  30. private int $statusCode;
  31.  
  32. /**
  33. * Gets the display returned by the last execution of the command or application.
  34. *
  35. * @throws \RuntimeException If it's called before the execute method
  36. */
  37. public function getDisplay(bool $normalize = false): string
  38. {
  39. if (!isset($this->output)) {
  40. throw new \RuntimeException('Output not initialized, did you execute the command before requesting the display?');
  41. }
  42.  
  43. rewind($this->output->getStream());
  44.  
  45. $display = stream_get_contents($this->output->getStream());
  46.  
  47. if ($normalize) {
  48. $display = str_replace(\PHP_EOL, "\n", $display);
  49. }
  50.  
  51. return $display;
  52. }
  53.  
  54. /**
  55. * Gets the output written to STDERR by the application.
  56. *
  57. * @param bool $normalize Whether to normalize end of lines to \n or not
  58. */
  59. public function getErrorOutput(bool $normalize = false): string
  60. {
  61. if (!$this->captureStreamsIndependently) {
  62. throw new \LogicException('The error output is not available when the tester is run without "capture_stderr_separately" option set.');
  63. }
  64.  
  65. rewind($this->output->getErrorOutput()->getStream());
  66.  
  67. $display = stream_get_contents($this->output->getErrorOutput()->getStream());
  68.  
  69. if ($normalize) {
  70. $display = str_replace(\PHP_EOL, "\n", $display);
  71. }
  72.  
  73. return $display;
  74. }
  75.  
  76. /**
  77. * Gets the input instance used by the last execution of the command or application.
  78. */
  79. public function getInput(): InputInterface
  80. {
  81. return $this->input;
  82. }
  83.  
  84. /**
  85. * Gets the output instance used by the last execution of the command or application.
  86. */
  87. public function getOutput(): OutputInterface
  88. {
  89. return $this->output;
  90. }
  91.  
  92. /**
  93. * Gets the status code returned by the last execution of the command or application.
  94. *
  95. * @throws \RuntimeException If it's called before the execute method
  96. */
  97. public function getStatusCode(): int
  98. {
  99. return $this->statusCode ?? throw new \RuntimeException('Status code not initialized, did you execute the command before requesting the status code?');
  100. }
  101.  
  102. public function assertCommandIsSuccessful(string $message = ''): void
  103. {
  104. Assert::assertThat($this->statusCode, new CommandIsSuccessful(), $message);
  105. }
  106.  
  107. /**
  108. * Sets the user inputs.
  109. *
  110. * @param array $inputs An array of strings representing each input
  111. * passed to the command input stream
  112. *
  113. * @return $this
  114. */
  115. public function setInputs(array $inputs): static
  116. {
  117. $this->inputs = $inputs;
  118.  
  119. return $this;
  120. }
  121.  
  122. /**
  123. * Initializes the output property.
  124. *
  125. * Available options:
  126. *
  127. * * decorated: Sets the output decorated flag
  128. * * verbosity: Sets the output verbosity flag
  129. * * capture_stderr_separately: Make output of stdOut and stdErr separately available
  130. */
  131. private function initOutput(array $options)
  132. {
  133. $this->captureStreamsIndependently = \array_key_exists('capture_stderr_separately', $options) && $options['capture_stderr_separately'];
  134. if (!$this->captureStreamsIndependently) {
  135. $this->output = new StreamOutput(fopen('php://memory', 'w', false));
  136. if (isset($options['decorated'])) {
  137. $this->output->setDecorated($options['decorated']);
  138. }
  139. if (isset($options['verbosity'])) {
  140. $this->output->setVerbosity($options['verbosity']);
  141. }
  142. } else {
  143. $this->output = new ConsoleOutput(
  144. $options['verbosity'] ?? ConsoleOutput::VERBOSITY_NORMAL,
  145. $options['decorated'] ?? null
  146. );
  147.  
  148. $errorOutput = new StreamOutput(fopen('php://memory', 'w', false));
  149. $errorOutput->setFormatter($this->output->getFormatter());
  150. $errorOutput->setVerbosity($this->output->getVerbosity());
  151. $errorOutput->setDecorated($this->output->isDecorated());
  152.  
  153. $reflectedOutput = new \ReflectionObject($this->output);
  154. $strErrProperty = $reflectedOutput->getProperty('stderr');
  155. $strErrProperty->setAccessible(true);
  156. $strErrProperty->setValue($this->output, $errorOutput);
  157.  
  158. $reflectedParent = $reflectedOutput->getParentClass();
  159. $streamProperty = $reflectedParent->getProperty('stream');
  160. $streamProperty->setAccessible(true);
  161. $streamProperty->setValue($this->output, fopen('php://memory', 'w', false));
  162. }
  163. }
  164.  
  165. /**
  166. * @return resource
  167. */
  168. private static function createStream(array $inputs)
  169. {
  170. $stream = fopen('php://memory', 'r+', false);
  171.  
  172. foreach ($inputs as $input) {
  173. fwrite($stream, $input.\PHP_EOL);
  174. }
  175.  
  176. rewind($stream);
  177.  
  178. return $stream;
  179. }
  180. }