/dev/tests/static/testsuite/Magento/Test/Integrity/Library/DependencyTest.php

https://gitlab.com/crazybutterfly815/magento2 · PHP · 158 lines · 111 code · 12 blank · 35 comment · 6 complexity · a8fac4dbfefb498f1a1111a4447f7a2c MD5 · raw file

  1. <?php
  2. /**
  3. * Copyright © 2016 Magento. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Test\Integrity\Library;
  7. use Magento\Framework\App\Utility\Files;
  8. use Magento\Framework\App\Utility\AggregateInvoker;
  9. use Magento\Framework\Component\ComponentRegistrar;
  10. use Magento\TestFramework\Integrity\Library\Injectable;
  11. use Magento\TestFramework\Integrity\Library\PhpParser\ParserFactory;
  12. use Magento\TestFramework\Integrity\Library\PhpParser\Tokens;
  13. use Zend\Code\Reflection\FileReflection;
  14. /**
  15. * Test check if Magento library components contain incorrect dependencies to application layer
  16. *
  17. */
  18. class DependencyTest extends \PHPUnit_Framework_TestCase
  19. {
  20. /**
  21. * Collect errors
  22. *
  23. * @var array
  24. */
  25. protected $errors = [];
  26. /**
  27. * Forbidden base namespaces
  28. *
  29. * @return array
  30. */
  31. protected function getForbiddenNamespaces()
  32. {
  33. return ['Magento'];
  34. }
  35. public function testCheckDependencies()
  36. {
  37. $invoker = new \Magento\Framework\App\Utility\AggregateInvoker($this);
  38. $invoker(
  39. /**
  40. * @param string $file
  41. */
  42. function ($file) {
  43. $componentRegistrar = new ComponentRegistrar();
  44. $fileReflection = new FileReflection($file);
  45. $tokens = new Tokens($fileReflection->getContents(), new ParserFactory());
  46. $tokens->parseContent();
  47. $dependencies = array_merge(
  48. (new Injectable())->getDependencies($fileReflection),
  49. $tokens->getDependencies()
  50. );
  51. $pattern = '#^(\\\\|)' . implode('|', $this->getForbiddenNamespaces()) . '\\\\#';
  52. foreach ($dependencies as $dependency) {
  53. $dependencyPaths = explode('/', $dependency);
  54. $dependencyPaths = array_slice($dependencyPaths, 2);
  55. $dependency = implode('\\', $dependencyPaths);
  56. $libraryPaths = $componentRegistrar->getPaths(ComponentRegistrar::LIBRARY);
  57. foreach ($libraryPaths as $libraryPath) {
  58. $filePath = str_replace('\\', '/', $libraryPath . '/' . $dependency . '.php');
  59. if (preg_match($pattern, $dependency) && !file_exists($filePath)) {
  60. $this->errors[$fileReflection->getFileName()][] = $dependency;
  61. }
  62. }
  63. }
  64. if (!empty($this->errors)) {
  65. $this->fail($this->getFailMessage());
  66. }
  67. },
  68. $this->libraryDataProvider()
  69. );
  70. }
  71. public function testAppCodeUsage()
  72. {
  73. $files = Files::init();
  74. $componentRegistrar = new ComponentRegistrar();
  75. $libPaths = $componentRegistrar->getPaths(ComponentRegistrar::LIBRARY);
  76. $invoker = new AggregateInvoker($this);
  77. $invoker(
  78. function ($file) use ($libPaths) {
  79. $content = file_get_contents($file);
  80. foreach ($libPaths as $libPath) {
  81. if (strpos($file, $libPath) === 0) {
  82. $this->assertSame(
  83. 0,
  84. preg_match('~(?<![a-z\\d_:]|->|function\\s)__\\s*\\(~iS', $content),
  85. 'Function __() is defined outside of the library and must not be used there. ' .
  86. 'Replacement suggestion: new \\Magento\\Framework\\Phrase()'
  87. );
  88. }
  89. }
  90. },
  91. $files->getPhpFiles(
  92. Files::INCLUDE_PUB_CODE |
  93. Files::INCLUDE_LIBS |
  94. Files::AS_DATA_SET |
  95. Files::INCLUDE_NON_CLASSES
  96. )
  97. );
  98. }
  99. /**
  100. * @inheritdoc
  101. */
  102. public function tearDown()
  103. {
  104. $this->errors = [];
  105. }
  106. /**
  107. * Prepare failed message
  108. *
  109. * @return string
  110. */
  111. protected function getFailMessage()
  112. {
  113. $failMessage = '';
  114. foreach ($this->errors as $class => $dependencies) {
  115. $failMessage .= $class . ' depends for non-library ' . (count($dependencies) > 1 ? 'classes ' : 'class ');
  116. foreach ($dependencies as $dependency) {
  117. $failMessage .= $dependency . ' ';
  118. }
  119. $failMessage = trim($failMessage) . PHP_EOL;
  120. }
  121. return $failMessage;
  122. }
  123. /**
  124. * Contains all library files
  125. *
  126. * @return array
  127. */
  128. public function libraryDataProvider()
  129. {
  130. // @TODO: remove this code when class Magento\Framework\Data\Collection will fixed
  131. $componentRegistrar = new ComponentRegistrar();
  132. include_once $componentRegistrar->getPath(ComponentRegistrar::LIBRARY, 'magento/framework')
  133. . '/Option/ArrayInterface.php';
  134. $blackList = Files::init()->readLists(__DIR__ . '/_files/blacklist.txt');
  135. $dataProvider = Files::init()->getPhpFiles(Files::INCLUDE_LIBS | Files::AS_DATA_SET);
  136. foreach ($dataProvider as $key => $data) {
  137. $file = str_replace(BP . '/', '', $data[0]);
  138. if (in_array($file, $blackList)) {
  139. unset($dataProvider[$key]);
  140. } else {
  141. include_once $data[0];
  142. }
  143. }
  144. return $dataProvider;
  145. }
  146. }