ErrorOutputTest.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. <?php
  2. /*
  3. * This file is part of PHP CS Fixer.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. * Dariusz Rumiński <dariusz.ruminski@gmail.com>
  7. *
  8. * This source file is subject to the MIT license that is bundled
  9. * with this source code in the file LICENSE.
  10. */
  11. namespace PhpCsFixer\Tests\Console\Output;
  12. use PhpCsFixer\Console\Output\ErrorOutput;
  13. use PhpCsFixer\Error\Error;
  14. use PhpCsFixer\Linter\LintingException;
  15. use PhpCsFixer\Tests\TestCase;
  16. use Symfony\Component\Console\Output\OutputInterface;
  17. use Symfony\Component\Console\Output\StreamOutput;
  18. /**
  19. * @author SpacePossum
  20. *
  21. * @internal
  22. *
  23. * @covers \PhpCsFixer\Console\Output\ErrorOutput
  24. */
  25. final class ErrorOutputTest extends TestCase
  26. {
  27. /**
  28. * @param int $verbosityLevel
  29. * @param int $lineNumber
  30. * @param int $exceptionLineNumber
  31. * @param string $process
  32. *
  33. * @dataProvider provideTestCases
  34. */
  35. public function testErrorOutput(Error $error, $verbosityLevel, $lineNumber, $exceptionLineNumber, $process)
  36. {
  37. $source = $error->getSource();
  38. $output = $this->createStreamOutput($verbosityLevel);
  39. $errorOutput = new ErrorOutput($output);
  40. $errorOutput->listErrors($process, [$error]);
  41. $displayed = $this->readFullStreamOutput($output);
  42. $startWith = sprintf(
  43. '
  44. Files that were not fixed due to errors reported during %s:
  45. 1) %s',
  46. $process,
  47. __FILE__
  48. );
  49. if ($verbosityLevel >= OutputInterface::VERBOSITY_VERY_VERBOSE) {
  50. $startWith .= sprintf(
  51. '
  52. '.'
  53. [%s] '.'
  54. %s (%d) '.'
  55. '.'
  56. ',
  57. \get_class($source),
  58. $source->getMessage(),
  59. $source->getCode()
  60. );
  61. }
  62. if ($verbosityLevel >= OutputInterface::VERBOSITY_DEBUG) {
  63. $startWith .= sprintf(
  64. '
  65. PhpCsFixer\Tests\Console\Output\ErrorOutputTest->getErrorAndLineNumber()
  66. in %s at line %d
  67. PhpCsFixer\Tests\Console\Output\ErrorOutputTest->provideTestCases()
  68. ReflectionMethod->invoke()
  69. ',
  70. __FILE__,
  71. $lineNumber
  72. );
  73. }
  74. static::assertStringStartsWith($startWith, $displayed);
  75. }
  76. public function provideTestCases()
  77. {
  78. $lineNumber = __LINE__;
  79. list($exceptionLineNumber, $error) = $this->getErrorAndLineNumber(); // note: keep call and __LINE__ separated with one line break
  80. ++$lineNumber;
  81. return [
  82. [$error, OutputInterface::VERBOSITY_NORMAL, $lineNumber, $exceptionLineNumber, 'VN'],
  83. [$error, OutputInterface::VERBOSITY_VERBOSE, $lineNumber, $exceptionLineNumber, 'VV'],
  84. [$error, OutputInterface::VERBOSITY_VERY_VERBOSE, $lineNumber, $exceptionLineNumber, 'VVV'],
  85. [$error, OutputInterface::VERBOSITY_DEBUG, $lineNumber, $exceptionLineNumber, 'DEBUG'],
  86. ];
  87. }
  88. public function testLintingExceptionOutputsAppliedFixersAndDiff()
  89. {
  90. $fixerName = uniqid('braces_');
  91. $diffSpecificContext = uniqid('added_');
  92. $diff = <<<EOT
  93. --- Original
  94. +++ New
  95. @@ @@
  96. same line
  97. -deleted
  98. +{$diffSpecificContext}
  99. EOT;
  100. $lintError = new Error(Error::TYPE_LINT, __FILE__, new LintingException(), [$fixerName], $diff);
  101. $noDiffLintFixerName = uniqid('no_diff_');
  102. $noDiffLintError = new Error(Error::TYPE_LINT, __FILE__, new LintingException(), [$noDiffLintFixerName]);
  103. $invalidErrorFixerName = uniqid('line_ending_');
  104. $invalidDiff = uniqid('invalid_diff_');
  105. $invalidError = new Error(Error::TYPE_INVALID, __FILE__, new LintingException(), [$invalidErrorFixerName], $invalidDiff);
  106. $output = $this->createStreamOutput(OutputInterface::VERBOSITY_VERY_VERBOSE);
  107. $errorOutput = new ErrorOutput($output);
  108. $errorOutput->listErrors(uniqid('process_'), [
  109. $lintError,
  110. $noDiffLintError,
  111. $invalidError,
  112. ]);
  113. $displayed = $this->readFullStreamOutput($output);
  114. static::assertContains($fixerName, $displayed);
  115. static::assertContains($diffSpecificContext, $displayed);
  116. static::assertContains($noDiffLintFixerName, $displayed);
  117. static::assertNotContains($invalidErrorFixerName, $displayed);
  118. static::assertNotContains($invalidDiff, $displayed);
  119. }
  120. /**
  121. * @param int $verbosityLevel
  122. *
  123. * @return StreamOutput
  124. */
  125. private function createStreamOutput($verbosityLevel)
  126. {
  127. $output = new StreamOutput(fopen('php://memory', 'w', false));
  128. $output->setDecorated(false);
  129. $output->setVerbosity($verbosityLevel);
  130. return $output;
  131. }
  132. /**
  133. * @param StreamOutput $output
  134. *
  135. * @return string
  136. */
  137. private function readFullStreamOutput($output)
  138. {
  139. rewind($output->getStream());
  140. $displayed = stream_get_contents($output->getStream());
  141. // normalize line breaks,
  142. // as we output using SF `writeln` we are not sure what line ending has been used as it is
  143. // based on the platform/console/terminal used
  144. return str_replace(PHP_EOL, "\n", $displayed);
  145. }
  146. private function getErrorAndLineNumber()
  147. {
  148. $lineNumber = __LINE__;
  149. $exception = new \RuntimeException(// note: keep exception constructor and __LINE__ separated with one line break
  150. 'PHPUnit RT',
  151. 888,
  152. new \InvalidArgumentException('PHPUnit IAE')
  153. );
  154. return [$lineNumber + 1, new Error(Error::TYPE_EXCEPTION, __FILE__, $exception)];
  155. }
  156. }