CacheTest.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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\Cache;
  13. use PhpCsFixer\Cache\Cache;
  14. use PhpCsFixer\Cache\CacheInterface;
  15. use PhpCsFixer\Cache\Signature;
  16. use PhpCsFixer\Cache\SignatureInterface;
  17. use PhpCsFixer\Config;
  18. use PhpCsFixer\Tests\TestCase;
  19. use PhpCsFixer\ToolInfo;
  20. /**
  21. * @author Andreas Möller <am@localheinz.com>
  22. *
  23. * @internal
  24. *
  25. * @covers \PhpCsFixer\Cache\Cache
  26. */
  27. final class CacheTest extends TestCase
  28. {
  29. public function testIsFinal(): void
  30. {
  31. $reflection = new \ReflectionClass(Cache::class);
  32. self::assertTrue($reflection->isFinal());
  33. }
  34. public function testImplementsCacheInterface(): void
  35. {
  36. $reflection = new \ReflectionClass(Cache::class);
  37. self::assertTrue($reflection->implementsInterface(CacheInterface::class));
  38. }
  39. public function testConstructorSetsValues(): void
  40. {
  41. $signature = $this->createSignatureDouble();
  42. $cache = new Cache($signature);
  43. self::assertSame($signature, $cache->getSignature());
  44. }
  45. public function testDefaults(): void
  46. {
  47. $signature = $this->createSignatureDouble();
  48. $cache = new Cache($signature);
  49. $file = 'test.php';
  50. self::assertFalse($cache->has($file));
  51. self::assertNull($cache->get($file));
  52. }
  53. public function testCanSetAndGetValue(): void
  54. {
  55. $signature = $this->createSignatureDouble();
  56. $cache = new Cache($signature);
  57. $file = 'test.php';
  58. $hash = md5('hello');
  59. $cache->set($file, $hash);
  60. self::assertTrue($cache->has($file));
  61. self::assertSame($hash, $cache->get($file));
  62. }
  63. public function testCanClearValue(): void
  64. {
  65. $signature = $this->createSignatureDouble();
  66. $cache = new Cache($signature);
  67. $file = 'test.php';
  68. $hash = md5('hello');
  69. $cache->set($file, $hash);
  70. $cache->clear($file);
  71. self::assertNull($cache->get($file));
  72. }
  73. public function testFromJsonThrowsInvalidArgumentExceptionIfJsonIsInvalid(): void
  74. {
  75. $this->expectException(\InvalidArgumentException::class);
  76. $json = '{"foo';
  77. Cache::fromJson($json);
  78. }
  79. /**
  80. * @param array<string, mixed> $data
  81. *
  82. * @dataProvider provideFromJsonThrowsInvalidArgumentExceptionIfJsonIsMissingKeyCases
  83. */
  84. public function testFromJsonThrowsInvalidArgumentExceptionIfJsonIsMissingKey(array $data): void
  85. {
  86. $this->expectException(\InvalidArgumentException::class);
  87. $json = json_encode($data, JSON_THROW_ON_ERROR);
  88. Cache::fromJson($json);
  89. }
  90. public static function provideFromJsonThrowsInvalidArgumentExceptionIfJsonIsMissingKeyCases(): iterable
  91. {
  92. $data = [
  93. 'php' => '7.1.2',
  94. 'version' => '2.0',
  95. 'rules' => [
  96. 'foo' => true,
  97. 'bar' => false,
  98. ],
  99. 'hashes' => [],
  100. ];
  101. return array_map(static function (string $missingKey) use ($data): array {
  102. unset($data[$missingKey]);
  103. return [
  104. $data,
  105. ];
  106. }, array_keys($data));
  107. }
  108. /**
  109. * @dataProvider provideCanConvertToAndFromJsonCases
  110. */
  111. public function testCanConvertToAndFromJson(SignatureInterface $signature): void
  112. {
  113. $cache = new Cache($signature);
  114. $file = 'test.php';
  115. $hash = md5('hello');
  116. $cache->set($file, $hash);
  117. $cached = Cache::fromJson($cache->toJson());
  118. self::assertTrue($cached->getSignature()->equals($signature));
  119. self::assertTrue($cached->has($file));
  120. self::assertSame($hash, $cached->get($file));
  121. }
  122. /**
  123. * @return iterable<array{Signature}>
  124. */
  125. public static function provideCanConvertToAndFromJsonCases(): iterable
  126. {
  127. $toolInfo = new ToolInfo();
  128. $config = new Config();
  129. yield [new Signature(
  130. PHP_VERSION,
  131. '2.0',
  132. ' ',
  133. "\r\n",
  134. [
  135. 'foo' => true,
  136. 'bar' => true,
  137. ]
  138. )];
  139. yield [new Signature(
  140. PHP_VERSION,
  141. $toolInfo->getVersion(),
  142. $config->getIndent(),
  143. $config->getLineEnding(),
  144. [
  145. // value encoded in ANSI, not UTF
  146. 'header_comment' => ['header' => 'Dariusz '.base64_decode('UnVtafFza2k=', true)],
  147. ]
  148. )];
  149. }
  150. public function testToJsonThrowsExceptionOnInvalid(): void
  151. {
  152. $signature = $this->createSignatureDouble();
  153. $cache = new Cache($signature);
  154. $this->expectException(
  155. \UnexpectedValueException::class
  156. );
  157. $this->expectExceptionMessage(
  158. 'Cannot encode cache signature to JSON, error: "Malformed UTF-8 characters, possibly incorrectly encoded". If you have non-UTF8 chars in your signature, like in license for `header_comment`, consider enabling `ext-mbstring` or install `symfony/polyfill-mbstring`.'
  159. );
  160. $cache->toJson();
  161. }
  162. private function createSignatureDouble(): SignatureInterface
  163. {
  164. return new class implements SignatureInterface {
  165. public function getPhpVersion(): string
  166. {
  167. return '7.1.0';
  168. }
  169. public function getFixerVersion(): string
  170. {
  171. return '2.2.0';
  172. }
  173. public function getIndent(): string
  174. {
  175. return ' ';
  176. }
  177. public function getLineEnding(): string
  178. {
  179. return PHP_EOL;
  180. }
  181. public function getRules(): array
  182. {
  183. return [
  184. "\xB1\x31" => true, // invalid UTF8 sequence
  185. ];
  186. }
  187. public function equals(SignatureInterface $signature): bool
  188. {
  189. throw new \LogicException('Not implemented.');
  190. }
  191. };
  192. }
  193. }