ComponentRegistrarFixture.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\TestFramework\Annotation;
  7. use RecursiveDirectoryIterator;
  8. use RecursiveIteratorIterator;
  9. use RegexIterator;
  10. /**
  11. * Implementation of the @magentoComponentsDir DocBlock annotation
  12. */
  13. class ComponentRegistrarFixture
  14. {
  15. /**
  16. * Annotation name
  17. */
  18. const ANNOTATION_NAME = 'magentoComponentsDir';
  19. /**#@+
  20. * Properties of components registrar
  21. */
  22. const REGISTRAR_CLASS = \Magento\Framework\Component\ComponentRegistrar::class;
  23. const PATHS_FIELD = 'paths';
  24. /**#@-*/
  25. /**
  26. * Fixtures base dir
  27. *
  28. * @var string
  29. */
  30. private $fixtureBaseDir;
  31. /**
  32. * Original values of registered components
  33. *
  34. * @var array
  35. */
  36. private $origComponents = null;
  37. /**
  38. * Constructor
  39. *
  40. * @param string $fixtureBaseDir
  41. */
  42. public function __construct($fixtureBaseDir)
  43. {
  44. $this->fixtureBaseDir = $fixtureBaseDir;
  45. }
  46. /**
  47. * Handler for 'startTest' event
  48. *
  49. * @param \PHPUnit\Framework\TestCase $test
  50. * @return void
  51. */
  52. public function startTest(\PHPUnit\Framework\TestCase $test)
  53. {
  54. $this->registerComponents($test);
  55. }
  56. /**
  57. * Handler for 'endTest' event
  58. *
  59. * @param \PHPUnit\Framework\TestCase $test
  60. * @return void
  61. *
  62. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  63. */
  64. public function endTest(\PHPUnit\Framework\TestCase $test)
  65. {
  66. $this->restoreComponents();
  67. }
  68. /**
  69. * Register fixture components
  70. *
  71. * @param \PHPUnit\Framework\TestCase $test
  72. */
  73. private function registerComponents(\PHPUnit\Framework\TestCase $test)
  74. {
  75. $annotations = $test->getAnnotations();
  76. $componentAnnotations = [];
  77. if (isset($annotations['class'][self::ANNOTATION_NAME])) {
  78. $componentAnnotations = array_merge($componentAnnotations, $annotations['class'][self::ANNOTATION_NAME]);
  79. }
  80. if (isset($annotations['method'][self::ANNOTATION_NAME])) {
  81. $componentAnnotations = array_merge($componentAnnotations, $annotations['method'][self::ANNOTATION_NAME]);
  82. }
  83. if (empty($componentAnnotations)) {
  84. return;
  85. }
  86. $componentAnnotations = array_unique($componentAnnotations);
  87. $reflection = new \ReflectionClass(self::REGISTRAR_CLASS);
  88. $paths = $reflection->getProperty(self::PATHS_FIELD);
  89. $paths->setAccessible(true);
  90. $this->origComponents = $paths->getValue();
  91. $paths->setAccessible(false);
  92. foreach ($componentAnnotations as $fixturePath) {
  93. $fixturesDir = $this->fixtureBaseDir . '/' . $fixturePath;
  94. if (!file_exists($fixturesDir)) {
  95. throw new \InvalidArgumentException(
  96. self::ANNOTATION_NAME . " fixture '$fixturePath' does not exist"
  97. );
  98. }
  99. $iterator = new RegexIterator(
  100. new RecursiveIteratorIterator(
  101. new RecursiveDirectoryIterator($fixturesDir, \FilesystemIterator::SKIP_DOTS)
  102. ),
  103. '/^.+\/registration\.php$/'
  104. );
  105. /**
  106. * @var \SplFileInfo $registrationFile
  107. */
  108. foreach ($iterator as $registrationFile) {
  109. require $registrationFile->getRealPath();
  110. }
  111. }
  112. }
  113. /**
  114. * Restore registered components list to the original
  115. */
  116. private function restoreComponents()
  117. {
  118. if (null !== $this->origComponents) {
  119. $reflection = new \ReflectionClass(self::REGISTRAR_CLASS);
  120. $paths = $reflection->getProperty(self::PATHS_FIELD);
  121. $paths->setAccessible(true);
  122. $paths->setValue($this->origComponents);
  123. $paths->setAccessible(false);
  124. $this->origComponents = null;
  125. }
  126. }
  127. }