PageRenderTime 26ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php

https://github.com/FabienD/symfony
PHP | 197 lines | 137 code | 41 blank | 19 comment | 1 complexity | 877af4bccfca149fb831895bb98288df MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Bridge\Twig\Tests\Command;
  11. use PHPUnit\Framework\TestCase;
  12. use Symfony\Bridge\Twig\Command\LintCommand;
  13. use Symfony\Component\Console\Application;
  14. use Symfony\Component\Console\Command\Command;
  15. use Symfony\Component\Console\Output\OutputInterface;
  16. use Symfony\Component\Console\Tester\CommandCompletionTester;
  17. use Symfony\Component\Console\Tester\CommandTester;
  18. use Twig\Environment;
  19. use Twig\Loader\FilesystemLoader;
  20. use Twig\TwigFilter;
  21. class LintCommandTest extends TestCase
  22. {
  23. private $files;
  24. public function testLintCorrectFile()
  25. {
  26. $tester = $this->createCommandTester();
  27. $filename = $this->createFile('{{ foo }}');
  28. $ret = $tester->execute(['filename' => [$filename]], ['verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false]);
  29. $this->assertEquals(0, $ret, 'Returns 0 in case of success');
  30. $this->assertStringContainsString('OK in', trim($tester->getDisplay()));
  31. }
  32. public function testLintIncorrectFile()
  33. {
  34. $tester = $this->createCommandTester();
  35. $filename = $this->createFile('{{ foo');
  36. $ret = $tester->execute(['filename' => [$filename]], ['decorated' => false]);
  37. $this->assertEquals(1, $ret, 'Returns 1 in case of error');
  38. $this->assertMatchesRegularExpression('/ERROR in \S+ \(line /', trim($tester->getDisplay()));
  39. }
  40. public function testLintFileNotReadable()
  41. {
  42. $this->expectException(\RuntimeException::class);
  43. $tester = $this->createCommandTester();
  44. $filename = $this->createFile('');
  45. unlink($filename);
  46. $tester->execute(['filename' => [$filename]], ['decorated' => false]);
  47. }
  48. public function testLintFileCompileTimeException()
  49. {
  50. $tester = $this->createCommandTester();
  51. $filename = $this->createFile("{{ 2|number_format(2, decimal_point='.', ',') }}");
  52. $ret = $tester->execute(['filename' => [$filename]], ['decorated' => false]);
  53. $this->assertEquals(1, $ret, 'Returns 1 in case of error');
  54. $this->assertMatchesRegularExpression('/ERROR in \S+ \(line /', trim($tester->getDisplay()));
  55. }
  56. /**
  57. * When deprecations are not reported by the command, the testsuite reporter will catch them so we need to mark the test as legacy.
  58. *
  59. * @group legacy
  60. */
  61. public function testLintFileWithNotReportedDeprecation()
  62. {
  63. $tester = $this->createCommandTester();
  64. $filename = $this->createFile('{{ foo|deprecated_filter }}');
  65. $ret = $tester->execute(['filename' => [$filename]], ['verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false]);
  66. $this->assertEquals(0, $ret, 'Returns 0 in case of success');
  67. $this->assertStringContainsString('OK in', trim($tester->getDisplay()));
  68. }
  69. public function testLintFileWithReportedDeprecation()
  70. {
  71. $tester = $this->createCommandTester();
  72. $filename = $this->createFile('{{ foo|deprecated_filter }}');
  73. $ret = $tester->execute(['filename' => [$filename], '--show-deprecations' => true], ['verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false]);
  74. $this->assertEquals(1, $ret, 'Returns 1 in case of error');
  75. $this->assertMatchesRegularExpression('/ERROR in \S+ \(line 1\)/', trim($tester->getDisplay()));
  76. $this->assertStringContainsString('Filter "deprecated_filter" is deprecated', trim($tester->getDisplay()));
  77. }
  78. /**
  79. * @group tty
  80. */
  81. public function testLintDefaultPaths()
  82. {
  83. $tester = $this->createCommandTester();
  84. $ret = $tester->execute([], ['verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false]);
  85. $this->assertEquals(0, $ret, 'Returns 0 in case of success');
  86. self::assertStringContainsString('OK in', trim($tester->getDisplay()));
  87. }
  88. public function testLintIncorrectFileWithGithubFormat()
  89. {
  90. $filename = $this->createFile('{{ foo');
  91. $tester = $this->createCommandTester();
  92. $tester->execute(['filename' => [$filename], '--format' => 'github'], ['decorated' => false]);
  93. self::assertEquals(1, $tester->getStatusCode(), 'Returns 1 in case of error');
  94. self::assertStringMatchesFormat('%A::error file=%s,line=1,col=0::Unexpected token "end of template" ("end of print statement" expected).%A', trim($tester->getDisplay()));
  95. }
  96. public function testLintAutodetectsGithubActionEnvironment()
  97. {
  98. $prev = getenv('GITHUB_ACTIONS');
  99. putenv('GITHUB_ACTIONS');
  100. try {
  101. putenv('GITHUB_ACTIONS=1');
  102. $filename = $this->createFile('{{ foo');
  103. $tester = $this->createCommandTester();
  104. $tester->execute(['filename' => [$filename]], ['decorated' => false]);
  105. self::assertStringMatchesFormat('%A::error file=%s,line=1,col=0::Unexpected token "end of template" ("end of print statement" expected).%A', trim($tester->getDisplay()));
  106. } finally {
  107. putenv('GITHUB_ACTIONS'.($prev ? "=$prev" : ''));
  108. }
  109. }
  110. /**
  111. * @dataProvider provideCompletionSuggestions
  112. */
  113. public function testComplete(array $input, array $expectedSuggestions)
  114. {
  115. $tester = new CommandCompletionTester($this->createCommand());
  116. $this->assertSame($expectedSuggestions, $tester->complete($input));
  117. }
  118. public function provideCompletionSuggestions()
  119. {
  120. yield 'option' => [['--format', ''], ['txt', 'json', 'github']];
  121. }
  122. private function createCommandTester(): CommandTester
  123. {
  124. return new CommandTester($this->createCommand());
  125. }
  126. private function createCommand(): Command
  127. {
  128. $environment = new Environment(new FilesystemLoader(\dirname(__DIR__).'/Fixtures/templates/'));
  129. $environment->addFilter(new TwigFilter('deprecated_filter', function ($v) {
  130. return $v;
  131. }, ['deprecated' => true]));
  132. $command = new LintCommand($environment);
  133. $application = new Application();
  134. $application->add($command);
  135. return $application->find('lint:twig');
  136. }
  137. private function createFile($content): string
  138. {
  139. $filename = tempnam(sys_get_temp_dir(), 'sf-');
  140. file_put_contents($filename, $content);
  141. $this->files[] = $filename;
  142. return $filename;
  143. }
  144. protected function setUp(): void
  145. {
  146. $this->files = [];
  147. }
  148. protected function tearDown(): void
  149. {
  150. foreach ($this->files as $file) {
  151. if (file_exists($file)) {
  152. @unlink($file);
  153. }
  154. }
  155. }
  156. }