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