CachingLinterTest.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4. * This file is part of PHP CS Fixer.
  5. *
  6. * (c) Fabien Potencier <fabien@symfony.com>
  7. * Dariusz Rumiński <dariusz.ruminski@gmail.com>
  8. *
  9. * This source file is subject to the MIT license that is bundled
  10. * with this source code in the file LICENSE.
  11. */
  12. namespace PhpCsFixer\Tests\Linter;
  13. use org\bovigo\vfs\vfsStream;
  14. use PhpCsFixer\Linter\CachingLinter;
  15. use PhpCsFixer\Linter\LinterInterface;
  16. use PhpCsFixer\Linter\LintingResultInterface;
  17. use PhpCsFixer\Tests\TestCase;
  18. /**
  19. * @author ntzm
  20. *
  21. * @internal
  22. *
  23. * @covers \PhpCsFixer\Linter\CachingLinter
  24. */
  25. final class CachingLinterTest extends TestCase
  26. {
  27. /**
  28. * @dataProvider provideIsAsyncCases
  29. */
  30. public function testIsAsync(bool $isAsync): void
  31. {
  32. $sublinter = $this->createLinterDouble($isAsync, [], []);
  33. $linter = new CachingLinter($sublinter);
  34. self::assertSame($isAsync, $linter->isAsync());
  35. }
  36. public static function provideIsAsyncCases(): iterable
  37. {
  38. yield [true];
  39. yield [false];
  40. }
  41. public function testLintFileIsCalledOnceOnSameContent(): void
  42. {
  43. $fs = vfsStream::setup('root', null, [
  44. 'foo.php' => '<?php echo "baz";',
  45. 'bar.php' => '<?php echo "baz";',
  46. 'baz.php' => '<?php echo "foobarbaz";',
  47. ]);
  48. $result1 = $this->createLintingResultDouble();
  49. $result2 = $this->createLintingResultDouble();
  50. $sublinter = $this->createLinterDouble(
  51. null,
  52. [
  53. $fs->url().'/foo.php' => $result1,
  54. $fs->url().'/baz.php' => $result2,
  55. ],
  56. [],
  57. );
  58. $linter = new CachingLinter($sublinter);
  59. self::assertSame($result1, $linter->lintFile($fs->url().'/foo.php'));
  60. self::assertSame($result1, $linter->lintFile($fs->url().'/foo.php'));
  61. self::assertSame($result1, $linter->lintFile($fs->url().'/bar.php'));
  62. self::assertSame($result2, $linter->lintFile($fs->url().'/baz.php'));
  63. }
  64. public function testLintSourceIsCalledOnceOnSameContent(): void
  65. {
  66. $result1 = $this->createLintingResultDouble();
  67. $result2 = $this->createLintingResultDouble();
  68. $sublinter = $this->createLinterDouble(
  69. null,
  70. [],
  71. [
  72. '<?php echo "baz";' => $result1,
  73. '<?php echo "foobarbaz";' => $result2,
  74. ],
  75. );
  76. $linter = new CachingLinter($sublinter);
  77. self::assertSame($result1, $linter->lintSource('<?php echo "baz";'));
  78. self::assertSame($result1, $linter->lintSource('<?php echo "baz";'));
  79. self::assertSame($result2, $linter->lintSource('<?php echo "foobarbaz";'));
  80. }
  81. /**
  82. * @param array<string, LintingResultInterface> $allowedLintFileCalls
  83. * @param array<string, LintingResultInterface> $allowedLintSourceCalls
  84. */
  85. private function createLinterDouble(?bool $isAsync, array $allowedLintFileCalls, array $allowedLintSourceCalls): LinterInterface
  86. {
  87. return new class($isAsync, $allowedLintFileCalls, $allowedLintSourceCalls) implements LinterInterface {
  88. private ?bool $isAsync;
  89. /** @var array<string, LintingResultInterface> */
  90. private array $allowedLintFileCalls;
  91. /** @var array<string, LintingResultInterface> */
  92. private array $allowedLintSourceCalls;
  93. /**
  94. * @param array<string, LintingResultInterface> $allowedLintFileCalls
  95. * @param array<string, LintingResultInterface> $allowedLintSourceCalls
  96. */
  97. public function __construct(?bool $isAsync, array $allowedLintFileCalls, array $allowedLintSourceCalls)
  98. {
  99. $this->isAsync = $isAsync;
  100. $this->allowedLintFileCalls = $allowedLintFileCalls;
  101. $this->allowedLintSourceCalls = $allowedLintSourceCalls;
  102. }
  103. public function isAsync(): bool
  104. {
  105. return $this->isAsync;
  106. }
  107. public function lintFile(string $path): LintingResultInterface
  108. {
  109. if (!isset($this->allowedLintFileCalls[$path])) {
  110. throw new \LogicException(\sprintf('File "%s" should not be linted.', $path));
  111. }
  112. $result = $this->allowedLintFileCalls[$path];
  113. unset($this->allowedLintFileCalls[$path]);
  114. return $result;
  115. }
  116. public function lintSource(string $source): LintingResultInterface
  117. {
  118. if (!isset($this->allowedLintSourceCalls[$source])) {
  119. throw new \LogicException(\sprintf('File "%s" should not be linted.', $source));
  120. }
  121. $result = $this->allowedLintSourceCalls[$source];
  122. unset($this->allowedLintSourceCalls[$source]);
  123. return $result;
  124. }
  125. };
  126. }
  127. private function createLintingResultDouble(): LintingResultInterface
  128. {
  129. return new class() implements LintingResultInterface {
  130. public function check(): void
  131. {
  132. throw new \LogicException('Not implemented.');
  133. }
  134. };
  135. }
  136. }