/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php

https://github.com/deviantintegral/symfony · PHP · 185 lines · 137 code · 30 blank · 18 comment · 3 complexity · d37d35b02526e1414c1e13cf5460de8f 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\Component\Config\Tests\Resource;
  11. use PHPUnit\Framework\TestCase;
  12. use Symfony\Component\Config\Resource\ReflectionClassResource;
  13. use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
  14. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  15. class ReflectionClassResourceTest extends TestCase
  16. {
  17. public function testToString()
  18. {
  19. $res = new ReflectionClassResource(new \ReflectionClass('ErrorException'));
  20. $this->assertSame('reflection.ErrorException', (string) $res);
  21. }
  22. public function testSerializeUnserialize()
  23. {
  24. $res = new ReflectionClassResource(new \ReflectionClass(DummyInterface::class));
  25. $ser = unserialize(serialize($res));
  26. $this->assertTrue($res->isFresh(0));
  27. $this->assertTrue($ser->isFresh(0));
  28. $this->assertSame((string) $res, (string) $ser);
  29. }
  30. public function testIsFresh()
  31. {
  32. $res = new ReflectionClassResource(new \ReflectionClass(__CLASS__));
  33. $mtime = filemtime(__FILE__);
  34. $this->assertTrue($res->isFresh($mtime), '->isFresh() returns true if the resource has not changed in same second');
  35. $this->assertTrue($res->isFresh($mtime + 10), '->isFresh() returns true if the resource has not changed');
  36. $this->assertTrue($res->isFresh($mtime - 86400), '->isFresh() returns true if the resource has not changed');
  37. }
  38. public function testIsFreshForDeletedResources()
  39. {
  40. $now = time();
  41. $tmp = sys_get_temp_dir().'/tmp.php';
  42. file_put_contents($tmp, '<?php class ReflectionClassResourceTestClass {}');
  43. require $tmp;
  44. $res = new ReflectionClassResource(new \ReflectionClass('ReflectionClassResourceTestClass'));
  45. $this->assertTrue($res->isFresh($now));
  46. unlink($tmp);
  47. $this->assertFalse($res->isFresh($now), '->isFresh() returns false if the resource does not exist');
  48. }
  49. /**
  50. * @dataProvider provideHashedSignature
  51. */
  52. public function testHashedSignature($changeExpected, $changedLine, $changedCode)
  53. {
  54. $code = <<<'EOPHP'
  55. /* 0*/
  56. /* 1*/ class %s extends ErrorException
  57. /* 2*/ {
  58. /* 3*/ const FOO = 123;
  59. /* 4*/
  60. /* 5*/ public $pub = array();
  61. /* 6*/
  62. /* 7*/ protected $prot;
  63. /* 8*/
  64. /* 9*/ private $priv;
  65. /*10*/
  66. /*11*/ public function pub($arg = null) {}
  67. /*12*/
  68. /*13*/ protected function prot($a = array()) {}
  69. /*14*/
  70. /*15*/ private function priv() {}
  71. /*16*/ }
  72. EOPHP;
  73. static $expectedSignature, $generateSignature;
  74. if (null === $expectedSignature) {
  75. eval(sprintf($code, $class = 'Foo'.str_replace('.', '_', uniqid('', true))));
  76. $r = new \ReflectionClass(ReflectionClassResource::class);
  77. $generateSignature = $r->getMethod('generateSignature');
  78. $generateSignature->setAccessible(true);
  79. $generateSignature = $generateSignature->getClosure($r->newInstanceWithoutConstructor());
  80. $expectedSignature = implode("\n", iterator_to_array($generateSignature(new \ReflectionClass($class))));
  81. }
  82. $code = explode("\n", $code);
  83. $code[$changedLine] = $changedCode;
  84. eval(sprintf(implode("\n", $code), $class = 'Foo'.str_replace('.', '_', uniqid('', true))));
  85. $signature = implode("\n", iterator_to_array($generateSignature(new \ReflectionClass($class))));
  86. if ($changeExpected) {
  87. $this->assertNotSame($expectedSignature, $signature);
  88. } else {
  89. $this->assertSame($expectedSignature, $signature);
  90. }
  91. }
  92. public function provideHashedSignature()
  93. {
  94. yield array(0, 0, "// line change\n\n");
  95. yield array(1, 0, '/** class docblock */');
  96. yield array(1, 1, 'abstract class %s');
  97. yield array(1, 1, 'final class %s');
  98. yield array(1, 1, 'class %s extends Exception');
  99. yield array(1, 1, 'class %s implements '.DummyInterface::class);
  100. yield array(1, 3, 'const FOO = 456;');
  101. yield array(1, 3, 'const BAR = 123;');
  102. yield array(1, 4, '/** pub docblock */');
  103. yield array(1, 5, 'protected $pub = array();');
  104. yield array(1, 5, 'public $pub = array(123);');
  105. yield array(1, 6, '/** prot docblock */');
  106. yield array(1, 7, 'private $prot;');
  107. yield array(0, 8, '/** priv docblock */');
  108. yield array(0, 9, 'private $priv = 123;');
  109. yield array(1, 10, '/** pub docblock */');
  110. yield array(1, 11, 'public function pub(...$arg) {}');
  111. yield array(1, 11, 'public function pub($arg = null): Foo {}');
  112. yield array(0, 11, "public function pub(\$arg = null) {\nreturn 123;\n}");
  113. yield array(1, 12, '/** prot docblock */');
  114. yield array(1, 13, 'protected function prot($a = array(123)) {}');
  115. yield array(0, 14, '/** priv docblock */');
  116. yield array(0, 15, '');
  117. }
  118. public function testEventSubscriber()
  119. {
  120. $res = new ReflectionClassResource(new \ReflectionClass(TestEventSubscriber::class));
  121. $this->assertTrue($res->isFresh(0));
  122. TestEventSubscriber::$subscribedEvents = array(123);
  123. $this->assertFalse($res->isFresh(0));
  124. $res = new ReflectionClassResource(new \ReflectionClass(TestEventSubscriber::class));
  125. $this->assertTrue($res->isFresh(0));
  126. }
  127. public function testServiceSubscriber()
  128. {
  129. $res = new ReflectionClassResource(new \ReflectionClass(TestServiceSubscriber::class));
  130. $this->assertTrue($res->isFresh(0));
  131. TestServiceSubscriber::$subscribedServices = array(123);
  132. $this->assertFalse($res->isFresh(0));
  133. $res = new ReflectionClassResource(new \ReflectionClass(TestServiceSubscriber::class));
  134. $this->assertTrue($res->isFresh(0));
  135. }
  136. }
  137. interface DummyInterface
  138. {
  139. }
  140. class TestEventSubscriber implements EventSubscriberInterface
  141. {
  142. public static $subscribedEvents = array();
  143. public static function getSubscribedEvents()
  144. {
  145. return self::$subscribedEvents;
  146. }
  147. }
  148. class TestServiceSubscriber implements ServiceSubscriberInterface
  149. {
  150. public static $subscribedServices = array();
  151. public static function getSubscribedServices()
  152. {
  153. return self::$subscribedServices;
  154. }
  155. }