CachingLinterTest.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  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. /**
  37. * @return iterable<array{bool}>
  38. */
  39. public static function provideIsAsyncCases(): iterable
  40. {
  41. yield [true];
  42. yield [false];
  43. }
  44. public function testLintFileIsCalledOnceOnSameContent(): void
  45. {
  46. $fs = vfsStream::setup('root', null, [
  47. 'foo.php' => '<?php echo "baz";',
  48. 'bar.php' => '<?php echo "baz";',
  49. 'baz.php' => '<?php echo "foobarbaz";',
  50. ]);
  51. $result1 = $this->createLintingResultDouble();
  52. $result2 = $this->createLintingResultDouble();
  53. $sublinter = $this->createLinterDouble(
  54. null,
  55. [
  56. $fs->url().'/foo.php' => $result1,
  57. $fs->url().'/baz.php' => $result2,
  58. ],
  59. [],
  60. );
  61. $linter = new CachingLinter($sublinter);
  62. self::assertSame($result1, $linter->lintFile($fs->url().'/foo.php'));
  63. self::assertSame($result1, $linter->lintFile($fs->url().'/foo.php'));
  64. self::assertSame($result1, $linter->lintFile($fs->url().'/bar.php'));
  65. self::assertSame($result2, $linter->lintFile($fs->url().'/baz.php'));
  66. }
  67. public function testLintSourceIsCalledOnceOnSameContent(): void
  68. {
  69. $result1 = $this->createLintingResultDouble();
  70. $result2 = $this->createLintingResultDouble();
  71. $sublinter = $this->createLinterDouble(
  72. null,
  73. [],
  74. [
  75. '<?php echo "baz";' => $result1,
  76. '<?php echo "foobarbaz";' => $result2,
  77. ],
  78. );
  79. $linter = new CachingLinter($sublinter);
  80. self::assertSame($result1, $linter->lintSource('<?php echo "baz";'));
  81. self::assertSame($result1, $linter->lintSource('<?php echo "baz";'));
  82. self::assertSame($result2, $linter->lintSource('<?php echo "foobarbaz";'));
  83. }
  84. /**
  85. * @param array<string, LintingResultInterface> $allowedLintFileCalls
  86. * @param array<string, LintingResultInterface> $allowedLintSourceCalls
  87. */
  88. private function createLinterDouble(?bool $isAsync, array $allowedLintFileCalls, array $allowedLintSourceCalls): LinterInterface
  89. {
  90. return new class($isAsync, $allowedLintFileCalls, $allowedLintSourceCalls) implements LinterInterface {
  91. private ?bool $isAsync;
  92. /** @var array<string, LintingResultInterface> */
  93. private array $allowedLintFileCalls;
  94. /** @var array<string, LintingResultInterface> */
  95. private array $allowedLintSourceCalls;
  96. /**
  97. * @param array<string, LintingResultInterface> $allowedLintFileCalls
  98. * @param array<string, LintingResultInterface> $allowedLintSourceCalls
  99. */
  100. public function __construct(?bool $isAsync, array $allowedLintFileCalls, array $allowedLintSourceCalls)
  101. {
  102. $this->isAsync = $isAsync;
  103. $this->allowedLintFileCalls = $allowedLintFileCalls;
  104. $this->allowedLintSourceCalls = $allowedLintSourceCalls;
  105. }
  106. public function isAsync(): bool
  107. {
  108. return $this->isAsync;
  109. }
  110. public function lintFile(string $path): LintingResultInterface
  111. {
  112. if (!isset($this->allowedLintFileCalls[$path])) {
  113. throw new \LogicException(\sprintf('File "%s" should not be linted.', $path));
  114. }
  115. $result = $this->allowedLintFileCalls[$path];
  116. unset($this->allowedLintFileCalls[$path]);
  117. return $result;
  118. }
  119. public function lintSource(string $source): LintingResultInterface
  120. {
  121. if (!isset($this->allowedLintSourceCalls[$source])) {
  122. throw new \LogicException(\sprintf('File "%s" should not be linted.', $source));
  123. }
  124. $result = $this->allowedLintSourceCalls[$source];
  125. unset($this->allowedLintSourceCalls[$source]);
  126. return $result;
  127. }
  128. };
  129. }
  130. private function createLintingResultDouble(): LintingResultInterface
  131. {
  132. return new class implements LintingResultInterface {
  133. public function check(): void
  134. {
  135. throw new \LogicException('Not implemented.');
  136. }
  137. };
  138. }
  139. }