DrupalComponentTest.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. <?php
  2. namespace Drupal\Tests\Component;
  3. use org\bovigo\vfs\vfsStream;
  4. use PHPUnit\Framework\TestCase;
  5. /**
  6. * General tests for \Drupal\Component that can't go anywhere else.
  7. *
  8. * @group Component
  9. */
  10. class DrupalComponentTest extends TestCase {
  11. /**
  12. * Tests that classes in Component do not use any Core class.
  13. */
  14. public function testNoCoreInComponent() {
  15. $component_path = dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__))) . '/lib/Drupal/Component';
  16. foreach ($this->findPhpClasses($component_path) as $class) {
  17. $this->assertNoCoreUsage($class);
  18. }
  19. }
  20. /**
  21. * Tests that classes in Component Tests do not use any Core class.
  22. */
  23. public function testNoCoreInComponentTests() {
  24. $component_path = dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__))) . '/tests/Drupal/Tests/Component';
  25. foreach ($this->findPhpClasses($component_path) as $class) {
  26. $this->assertNoCoreUsage($class);
  27. }
  28. }
  29. /**
  30. * Tests LICENSE.txt is present and has the correct content.
  31. *
  32. * @param $component_path
  33. * The path to the component.
  34. * @dataProvider \Drupal\Tests\Component\DrupalComponentTest::getComponents
  35. */
  36. public function testComponentLicence($component_path) {
  37. $this->assertFileExists($component_path . DIRECTORY_SEPARATOR . 'LICENSE.txt');
  38. $this->assertSame('e84dac1d9fbb5a4a69e38654ce644cea769aa76b', hash_file('sha1', $component_path . DIRECTORY_SEPARATOR . 'LICENSE.txt'));
  39. }
  40. /**
  41. * Data provider.
  42. *
  43. * @return array
  44. */
  45. public function getComponents() {
  46. $root_component_path = dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__))) . '/lib/Drupal/Component';
  47. $component_paths = [];
  48. foreach (new \DirectoryIterator($root_component_path) as $file) {
  49. if ($file->isDir() && !$file->isDot()) {
  50. $component_paths[$file->getBasename()] = [$file->getPathname()];
  51. }
  52. }
  53. return $component_paths;
  54. }
  55. /**
  56. * Searches a directory recursively for PHP classes.
  57. *
  58. * @param string $dir
  59. * The full path to the directory that should be checked.
  60. *
  61. * @return array
  62. * An array of class paths.
  63. */
  64. protected function findPhpClasses($dir) {
  65. $classes = [];
  66. foreach (new \DirectoryIterator($dir) as $file) {
  67. if ($file->isDir() && !$file->isDot()) {
  68. $classes = array_merge($classes, $this->findPhpClasses($file->getPathname()));
  69. }
  70. elseif ($file->getExtension() == 'php') {
  71. $classes[] = $file->getPathname();
  72. }
  73. }
  74. return $classes;
  75. }
  76. /**
  77. * Asserts that the given class is not using any class from Core namespace.
  78. *
  79. * @param string $class_path
  80. * The full path to the class that should be checked.
  81. */
  82. protected function assertNoCoreUsage($class_path) {
  83. $contents = file_get_contents($class_path);
  84. preg_match_all('/^.*Drupal\\\Core.*$/m', $contents, $matches);
  85. $matches = array_filter($matches[0], function ($line) {
  86. // Filter references to @see as they don't really matter.
  87. return strpos($line, '@see') === FALSE;
  88. });
  89. $this->assertEmpty($matches, "Checking for illegal reference to 'Drupal\\Core' namespace in $class_path");
  90. }
  91. /**
  92. * Data provider for testAssertNoCoreUseage().
  93. *
  94. * @return array
  95. * Data for testAssertNoCoreUseage() in the form:
  96. * - TRUE if the test passes, FALSE otherwise.
  97. * - File data as a string. This will be used as a virtual file.
  98. */
  99. public function providerAssertNoCoreUseage() {
  100. return [
  101. [
  102. TRUE,
  103. '@see \\Drupal\\Core\\Something',
  104. ],
  105. [
  106. FALSE,
  107. '\\Drupal\\Core\\Something',
  108. ],
  109. [
  110. FALSE,
  111. "@see \\Drupal\\Core\\Something\n" .
  112. '\\Drupal\\Core\\Something',
  113. ],
  114. [
  115. FALSE,
  116. "\\Drupal\\Core\\Something\n" .
  117. '@see \\Drupal\\Core\\Something',
  118. ],
  119. ];
  120. }
  121. /**
  122. * @covers \Drupal\Tests\Component\DrupalComponentTest::assertNoCoreUsage
  123. * @dataProvider providerAssertNoCoreUseage
  124. */
  125. public function testAssertNoCoreUseage($expected_pass, $file_data) {
  126. // Set up a virtual file to read.
  127. $vfs_root = vfsStream::setup('root');
  128. vfsStream::newFile('Test.php')->at($vfs_root)->setContent($file_data);
  129. $file_uri = vfsStream::url('root/Test.php');
  130. try {
  131. $pass = TRUE;
  132. $this->assertNoCoreUsage($file_uri);
  133. }
  134. catch (\PHPUnit_Framework_AssertionFailedError $e) {
  135. $pass = FALSE;
  136. }
  137. $this->assertEquals($expected_pass, $pass, $expected_pass ?
  138. 'Test caused a false positive' :
  139. 'Test failed to detect Core usage');
  140. }
  141. }