From 94ccb5c98cd44878f83f79a75f6219944c3b3338 Mon Sep 17 00:00:00 2001 From: Simon Praetorius Date: Thu, 22 Aug 2019 15:39:54 +0200 Subject: [PATCH 1/8] [TASK] Sanitize namespace input in component loader --- Classes/Utility/ComponentLoader.php | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/Classes/Utility/ComponentLoader.php b/Classes/Utility/ComponentLoader.php index 8dc1e0d..82611cb 100644 --- a/Classes/Utility/ComponentLoader.php +++ b/Classes/Utility/ComponentLoader.php @@ -37,6 +37,10 @@ public function __construct() */ public function addNamespace(string $namespace, string $path): self { + // Sanitize namespace data + $namespace = $this->sanitizeNamespace($namespace); + $path = $this->sanitizePath($path); + $this->namespaces[$namespace] = $path; return $this; } @@ -61,9 +65,15 @@ public function removeNamespace(string $namespace): self */ public function setNamespaces(array $namespaces): self { + // Make sure that namespaces are sanitized + $this->namespaces = []; + foreach ($namespaces as $namespace => $path) { + $this->addNamespace($namespace, $path); + } + // Order by namespace specificity arsort($namespaces); - $this->namespaces = $namespaces; + return $this; } @@ -94,8 +104,6 @@ public function findComponent(string $class, string $ext = '.html') // Walk through available namespaces, ordered from specific to unspecific $class = ltrim($class, '\\'); foreach ($this->namespaces as $namespace => $path) { - $namespace = ltrim($namespace, '\\'); - // No match, skip to next if (strpos($class, $namespace) !== 0) { continue; @@ -103,8 +111,8 @@ public function findComponent(string $class, string $ext = '.html') $componentParts = explode('\\', trim(substr($class, strlen($namespace)), '\\')); - $componentPath = rtrim($path, '/') . '/' . implode('/', $componentParts) . '/' . end($componentParts); - $componentFile = $componentPath . $ext; + $componentPath = $path . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $componentParts); + $componentFile = $componentPath . DIRECTORY_SEPARATOR . end($componentParts) . $ext; // Check if component file exists if (file_exists($componentFile)) { @@ -115,4 +123,14 @@ public function findComponent(string $class, string $ext = '.html') return null; } + + protected function sanitizeNamespace(string $namespace): string + { + return trim($namespace, '\\'); + } + + protected function sanitizePath(string $path): string + { + return rtrim($path, DIRECTORY_SEPARATOR); + } } From 5ab357f132564dbac8e904501c29ae85cb195557 Mon Sep 17 00:00:00 2001 From: Simon Praetorius Date: Thu, 22 Aug 2019 15:40:26 +0200 Subject: [PATCH 2/8] [BUGFIX] Order component namespaces by correct specificity --- Classes/Utility/ComponentLoader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/Utility/ComponentLoader.php b/Classes/Utility/ComponentLoader.php index 82611cb..521b966 100644 --- a/Classes/Utility/ComponentLoader.php +++ b/Classes/Utility/ComponentLoader.php @@ -72,7 +72,7 @@ public function setNamespaces(array $namespaces): self } // Order by namespace specificity - arsort($namespaces); + krsort($this->namespaces); return $this; } From a2b0f9a13b9ebc8dea40a3620c2a7ac1373c5906 Mon Sep 17 00:00:00 2001 From: Simon Praetorius Date: Thu, 22 Aug 2019 15:41:22 +0200 Subject: [PATCH 3/8] [BUGFIX] Prevent overlapping namespaces for components --- Classes/Utility/ComponentLoader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/Utility/ComponentLoader.php b/Classes/Utility/ComponentLoader.php index 521b966..5c602a1 100644 --- a/Classes/Utility/ComponentLoader.php +++ b/Classes/Utility/ComponentLoader.php @@ -105,7 +105,7 @@ public function findComponent(string $class, string $ext = '.html') $class = ltrim($class, '\\'); foreach ($this->namespaces as $namespace => $path) { // No match, skip to next - if (strpos($class, $namespace) !== 0) { + if (strpos($class, $namespace . '\\') !== 0) { continue; } From 7fe7f021bc6c984ecd3600b3217e76b9bb141a9b Mon Sep 17 00:00:00 2001 From: Simon Praetorius Date: Thu, 22 Aug 2019 15:41:56 +0200 Subject: [PATCH 4/8] [BUGFIX] Fix caching issue with different component formats --- Classes/Utility/ComponentLoader.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Classes/Utility/ComponentLoader.php b/Classes/Utility/ComponentLoader.php index 5c602a1..255792e 100644 --- a/Classes/Utility/ComponentLoader.php +++ b/Classes/Utility/ComponentLoader.php @@ -97,8 +97,9 @@ public function getNamespaces(): array public function findComponent(string $class, string $ext = '.html') { // Try cache first - if (isset($this->componentsCache[$class])) { - return $this->componentsCache[$class] . $ext; + $cacheIdentifier = $class . '|' . $ext; + if (isset($this->componentsCache[$cacheIdentifier])) { + return $this->componentsCache[$cacheIdentifier]; } // Walk through available namespaces, ordered from specific to unspecific @@ -116,7 +117,7 @@ public function findComponent(string $class, string $ext = '.html') // Check if component file exists if (file_exists($componentFile)) { - $this->componentsCache[$class] = $componentPath; + $this->componentsCache[$cacheIdentifier] = $componentFile; return $componentFile; } } From 070b5d26573bc9ab1f2414ac2ce560e0fa1488db Mon Sep 17 00:00:00 2001 From: Simon Praetorius Date: Thu, 22 Aug 2019 15:42:45 +0200 Subject: [PATCH 5/8] [FEATURE] Add method to obtain all available components in a namespace --- Classes/Utility/ComponentLoader.php | 40 +++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/Classes/Utility/ComponentLoader.php b/Classes/Utility/ComponentLoader.php index 255792e..2312bf1 100644 --- a/Classes/Utility/ComponentLoader.php +++ b/Classes/Utility/ComponentLoader.php @@ -125,6 +125,46 @@ public function findComponent(string $class, string $ext = '.html') return null; } + public function findComponentsInNamespace(string $namespace, string $ext = '.html'): array + { + if (!isset($this->namespaces[$namespace])) { + return []; + } + + return $this->scanForComponents( + $this->namespaces[$namespace], + $ext, + $namespace + ); + } + + protected function scanForComponents(string $path, string $ext, string $namespace): array + { + $components = []; + + $componentCandidates = scandir($path); + foreach ($componentCandidates as $componentName) { + $componentPath = $path . DIRECTORY_SEPARATOR . $componentName; + if ($componentName === '.' || $componentName === '..' || !is_dir($componentPath)) { + continue; + } + + $componentNamespace = $namespace . '\\' . $componentName; + $componentFile = $componentPath . DIRECTORY_SEPARATOR . $componentName . $ext; + + if (file_exists($componentFile)) { + $components[$componentNamespace] = $componentFile; + } + + $components = array_merge( + $components, + $this->scanForComponents($componentPath, $ext, $componentNamespace) + ); + } + + return $components; + } + protected function sanitizeNamespace(string $namespace): string { return trim($namespace, '\\'); From 161bc2dc38fd861ab2b9ec68169c8e1fe8677a5d Mon Sep 17 00:00:00 2001 From: Simon Praetorius Date: Thu, 22 Aug 2019 15:43:31 +0200 Subject: [PATCH 6/8] [TASK] Add unit tests for ComponentLoader --- .travis.yml | 2 +- .../ComponentLoader/Atom/Button/Button.html | 0 .../ComponentLoader/Atom/Button/Button.test | 0 .../ComponentLoader/Atom/Link/Link.html | 0 .../ComponentLoader/Atom/Link/Link.test | 0 .../ComponentLoader/Example/Example.html | 0 .../Molecule/Teaser/Headline/Headline.html | 0 .../Molecule/Teaser/Teaser.html | 0 Tests/Unit/ComponentLoaderTest.php | 214 ++++++++++++++++++ 9 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 Tests/Fixtures/ComponentLoader/Atom/Button/Button.html create mode 100644 Tests/Fixtures/ComponentLoader/Atom/Button/Button.test create mode 100644 Tests/Fixtures/ComponentLoader/Atom/Link/Link.html create mode 100644 Tests/Fixtures/ComponentLoader/Atom/Link/Link.test create mode 100644 Tests/Fixtures/ComponentLoader/Example/Example.html create mode 100644 Tests/Fixtures/ComponentLoader/Molecule/Teaser/Headline/Headline.html create mode 100644 Tests/Fixtures/ComponentLoader/Molecule/Teaser/Teaser.html create mode 100644 Tests/Unit/ComponentLoaderTest.php diff --git a/.travis.yml b/.travis.yml index 7007162..6361108 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,4 +11,4 @@ before_script: - composer install --prefer-dist script: - composer lint - #- composer test + - composer test diff --git a/Tests/Fixtures/ComponentLoader/Atom/Button/Button.html b/Tests/Fixtures/ComponentLoader/Atom/Button/Button.html new file mode 100644 index 0000000..e69de29 diff --git a/Tests/Fixtures/ComponentLoader/Atom/Button/Button.test b/Tests/Fixtures/ComponentLoader/Atom/Button/Button.test new file mode 100644 index 0000000..e69de29 diff --git a/Tests/Fixtures/ComponentLoader/Atom/Link/Link.html b/Tests/Fixtures/ComponentLoader/Atom/Link/Link.html new file mode 100644 index 0000000..e69de29 diff --git a/Tests/Fixtures/ComponentLoader/Atom/Link/Link.test b/Tests/Fixtures/ComponentLoader/Atom/Link/Link.test new file mode 100644 index 0000000..e69de29 diff --git a/Tests/Fixtures/ComponentLoader/Example/Example.html b/Tests/Fixtures/ComponentLoader/Example/Example.html new file mode 100644 index 0000000..e69de29 diff --git a/Tests/Fixtures/ComponentLoader/Molecule/Teaser/Headline/Headline.html b/Tests/Fixtures/ComponentLoader/Molecule/Teaser/Headline/Headline.html new file mode 100644 index 0000000..e69de29 diff --git a/Tests/Fixtures/ComponentLoader/Molecule/Teaser/Teaser.html b/Tests/Fixtures/ComponentLoader/Molecule/Teaser/Teaser.html new file mode 100644 index 0000000..e69de29 diff --git a/Tests/Unit/ComponentLoaderTest.php b/Tests/Unit/ComponentLoaderTest.php new file mode 100644 index 0000000..1090345 --- /dev/null +++ b/Tests/Unit/ComponentLoaderTest.php @@ -0,0 +1,214 @@ +loader = new ComponentLoader(); + } + + protected function getFixturePath($fixtureName) + { + return dirname(__FILE__) . '/../Fixtures/' . $fixtureName; + } + + public function addNamespaceProvider() + { + return [ + 'namespaceWithLeadingTrailingBackslash' => [ + '\\Vendor\\Extension\\Category\\', + '/path/to/components', + [ + 'Vendor\\Extension\\Category' => '/path/to/components' + ] + ], + 'pathWithTrailingSlash' => [ + 'Vendor\\Extension\\Category\\', + '/path/to/components/', + [ + 'Vendor\\Extension\\Category' => '/path/to/components' + ] + ] + ]; + } + + /** + * @test + * @dataProvider addNamespaceProvider + */ + public function addNamespace(string $namespace, string $path, array $namespaces) + { + $this->loader->addNamespace($namespace, $path); + $this->assertEquals( + $namespaces, + $this->loader->getNamespaces() + ); + } + + /** + * @test + * @depends addNamespace + */ + public function removeNamespace() + { + $namespace = 'Vendor\\Extension\\Category'; + $this->loader + ->addNamespace($namespace, 'some/path') + ->removeNamespace($namespace); + + $this->assertEquals( + [], + $this->loader->getNamespaces() + ); + } + + public function setNamespacesProvider() + { + return [ + 'case1' => [ + [ + 'Sitegeist\\Fixtures\\ComponentLoader' => '/case1/path1', + 'Sitegeist\\Fixtures\\Component\\Loader' => '/case1/path2', + 'Sitegeist\\Fixtures\\ComponentLoader\\Test' => '/case1/path3', + 'Vendor\\Test\\Namespace' => '/case1/path4', + '\\Sitegeist\\Fixtures\\ComponentLoader' => '/case1/path5', + '\\Sitegeist\\Fixtures\\ComponentLoader\\' => '/case1/path6', + '\\Sitegeist\\Fixtures\\AnotherTest\\' => '/case1/path7', + '\\Sitegeist\\Fixtures\\Test\\' => '/case1/path8' + ], + [ + 'Vendor\\Test\\Namespace' => '/case1/path4', + 'Sitegeist\\Fixtures\\Test' => '/case1/path8', + 'Sitegeist\\Fixtures\\AnotherTest' => '/case1/path7', + 'Sitegeist\\Fixtures\\ComponentLoader\\Test' => '/case1/path3', + 'Sitegeist\\Fixtures\\ComponentLoader' => '/case1/path6', + 'Sitegeist\\Fixtures\\Component\\Loader' => '/case1/path2' + ], + ] + ]; + } + + /** + * @test + * @dataProvider setNamespacesProvider + */ + public function setNamespaces(array $namespaces, array $sortedNamespaces) + { + $this->loader->setNamespaces($namespaces); + $this->assertEquals($sortedNamespaces, $this->loader->getNamespaces()); + } + + public function findComponentProvider() + { + return [ + 'existingComponent' => [ + 'Sitegeist\\Fixtures\\ComponentLoader\\Atom\\Button', + '.html', + $this->getFixturePath('ComponentLoader/Atom/Button/Button.html') + ], + 'existingComponentFileExtension' => [ + 'Sitegeist\\Fixtures\\ComponentLoader\\Atom\\Button', + '.test', + $this->getFixturePath('ComponentLoader/Atom/Button/Button.test') + ], + 'existingComponentFirstLevel' => [ + 'Sitegeist\\Fixtures\\ComponentLoader\\Example', + '.html', + $this->getFixturePath('ComponentLoader/Example/Example.html') + ], + 'existingComponentThirdLevel' => [ + 'Sitegeist\\Fixtures\\ComponentLoader\\Molecule\\Teaser\\Headline', + '.html', + $this->getFixturePath('ComponentLoader/Molecule/Teaser/Headline/Headline.html') + ], + 'nonexistingComponent' => [ + 'Sitegeist\\Fixtures\\ComponentLoader\\Atom\\Label', + '.html', + null + ], + 'nonexistingComponentFileExtension' => [ + 'Sitegeist\\Fixtures\\ComponentLoader\\Atom\\Button', + '.nonexisting', + null + ], + 'nonexistingComponentNamespace' => [ + 'Sitegeist\\Fixtures\\Nonexisting\\Component', + '.html', + null + ], + ]; + } + + /** + * @test + * @depends addNamespace + * @dataProvider findComponentProvider + */ + public function findComponent(string $componentIdentifier, string $fileExtension, $result) + { + $this->loader->addNamespace( + 'Sitegeist\\Fixtures\\ComponentLoader', + $this->getFixturePath('ComponentLoader') + ); + + // Test uncached version + $this->assertEquals( + $result, + $this->loader->findComponent($componentIdentifier, $fileExtension) + ); + + // Test cached version + $this->assertEquals( + $result, + $this->loader->findComponent($componentIdentifier, $fileExtension) + ); + } + + public function findComponentsInNamespaceProvider() + { + return [ + 'html' => [ + '.html', + [ + 'Sitegeist\\Fixtures\\ComponentLoader\\Atom\\Button' => $this->getFixturePath('ComponentLoader/Atom/Button/Button.html'), + 'Sitegeist\\Fixtures\\ComponentLoader\\Atom\\Link' => $this->getFixturePath('ComponentLoader/Atom/Link/Link.html'), + 'Sitegeist\\Fixtures\\ComponentLoader\\Example' => $this->getFixturePath('ComponentLoader/Example/Example.html'), + 'Sitegeist\\Fixtures\\ComponentLoader\\Molecule\\Teaser' => $this->getFixturePath('ComponentLoader/Molecule/Teaser/Teaser.html'), + 'Sitegeist\\Fixtures\\ComponentLoader\\Molecule\\Teaser\\Headline' => $this->getFixturePath('ComponentLoader/Molecule/Teaser/Headline/Headline.html') + ] + ], + 'test' => [ + '.test', + [ + 'Sitegeist\\Fixtures\\ComponentLoader\\Atom\\Button' => $this->getFixturePath('ComponentLoader/Atom/Button/Button.test'), + 'Sitegeist\\Fixtures\\ComponentLoader\\Atom\\Link' => $this->getFixturePath('ComponentLoader/Atom/Link/Link.test') + ] + ] + ]; + } + + /** + * @test + * @depends addNamespace + * @dataProvider findComponentsInNamespaceProvider + */ + public function findComponentsInNamespace(string $fileExtension, array $result) + { + $namespace = 'Sitegeist\\Fixtures\\ComponentLoader'; + $this->loader->addNamespace( + $namespace, + $this->getFixturePath('ComponentLoader') + ); + + $this->assertEquals( + $result, + $this->loader->findComponentsInNamespace($namespace, $fileExtension) + ); + } +} From 218e7ae06176293c367698dfe4d787a06ecfce67 Mon Sep 17 00:00:00 2001 From: Simon Praetorius Date: Thu, 22 Aug 2019 16:00:28 +0200 Subject: [PATCH 7/8] [TASK] Add comments for new ComponentLoader methods --- Classes/Utility/ComponentLoader.php | 32 +++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/Classes/Utility/ComponentLoader.php b/Classes/Utility/ComponentLoader.php index 2312bf1..7598800 100644 --- a/Classes/Utility/ComponentLoader.php +++ b/Classes/Utility/ComponentLoader.php @@ -125,6 +125,14 @@ public function findComponent(string $class, string $ext = '.html') return null; } + /** + * Provides a list of all components that are available in the specified component namespace + * + * @param string $namespace + * @param string $ext + * @return array Array of components where the keys contain the component identifier (FQCN) + * and the values contain the path to the component + */ public function findComponentsInNamespace(string $namespace, string $ext = '.html'): array { if (!isset($this->namespaces[$namespace])) { @@ -138,6 +146,14 @@ public function findComponentsInNamespace(string $namespace, string $ext = '.htm ); } + /** + * Searches for component files in a directory and maps them to their namespace + * + * @param string $path + * @param string $ext + * @param string $namespace + * @return array + */ protected function scanForComponents(string $path, string $ext, string $namespace): array { $components = []; @@ -145,6 +161,8 @@ protected function scanForComponents(string $path, string $ext, string $namespac $componentCandidates = scandir($path); foreach ($componentCandidates as $componentName) { $componentPath = $path . DIRECTORY_SEPARATOR . $componentName; + + // Only search for directories if ($componentName === '.' || $componentName === '..' || !is_dir($componentPath)) { continue; } @@ -152,10 +170,12 @@ protected function scanForComponents(string $path, string $ext, string $namespac $componentNamespace = $namespace . '\\' . $componentName; $componentFile = $componentPath . DIRECTORY_SEPARATOR . $componentName . $ext; + // Only match folders that contain a component file if (file_exists($componentFile)) { $components[$componentNamespace] = $componentFile; } + // Continue recursively $components = array_merge( $components, $this->scanForComponents($componentPath, $ext, $componentNamespace) @@ -165,11 +185,23 @@ protected function scanForComponents(string $path, string $ext, string $namespac return $components; } + /** + * Sanitizes a PHP namespace for use in the component loader + * + * @param string $namespace + * @return string + */ protected function sanitizeNamespace(string $namespace): string { return trim($namespace, '\\'); } + /** + * Sanitizes a path for use in the component loader + * + * @param string $path + * @return string + */ protected function sanitizePath(string $path): string { return rtrim($path, DIRECTORY_SEPARATOR); From d53c9c61e3accd858c956aa91c964f25d8427121 Mon Sep 17 00:00:00 2001 From: Simon Praetorius Date: Mon, 26 Aug 2019 18:10:06 +0200 Subject: [PATCH 8/8] [BUGFIX] Prevent infinite loops caused by symlinks --- Classes/Utility/ComponentLoader.php | 21 +++++++++++++------ .../Atom/ComponentLoaderSymlink | 1 + .../ComponentLoader/Molecule/Circular | 1 + .../Fixtures/ComponentLoader/Molecule/Example | 1 + .../ComponentLoaderSymlink.html | 0 Tests/Unit/ComponentLoaderTest.php | 3 ++- 6 files changed, 20 insertions(+), 7 deletions(-) create mode 120000 Tests/Fixtures/ComponentLoader/Atom/ComponentLoaderSymlink create mode 120000 Tests/Fixtures/ComponentLoader/Molecule/Circular create mode 120000 Tests/Fixtures/ComponentLoader/Molecule/Example create mode 100644 Tests/Fixtures/ComponentLoaderSymlink/ComponentLoaderSymlink.html diff --git a/Classes/Utility/ComponentLoader.php b/Classes/Utility/ComponentLoader.php index 7598800..e556120 100644 --- a/Classes/Utility/ComponentLoader.php +++ b/Classes/Utility/ComponentLoader.php @@ -139,10 +139,12 @@ public function findComponentsInNamespace(string $namespace, string $ext = '.htm return []; } + $scannedPaths = []; return $this->scanForComponents( $this->namespaces[$namespace], $ext, - $namespace + $namespace, + $scannedPaths ); } @@ -152,20 +154,27 @@ public function findComponentsInNamespace(string $namespace, string $ext = '.htm * @param string $path * @param string $ext * @param string $namespace + * @param array $scannedPaths Collection of paths that have already been scanned for components; + * this prevents infinite loops caused by circular symlinks * @return array */ - protected function scanForComponents(string $path, string $ext, string $namespace): array + protected function scanForComponents(string $path, string $ext, string $namespace, array &$scannedPaths): array { $components = []; $componentCandidates = scandir($path); foreach ($componentCandidates as $componentName) { - $componentPath = $path . DIRECTORY_SEPARATOR . $componentName; + // Skip relative links + if ($componentName === '.' || $componentName === '..') { + continue; + } - // Only search for directories - if ($componentName === '.' || $componentName === '..' || !is_dir($componentPath)) { + // Only search for directories and prevent infinite loops + $componentPath = realpath($path . DIRECTORY_SEPARATOR . $componentName); + if (!is_dir($componentPath) || isset($scannedPaths[$componentPath])) { continue; } + $scannedPaths[$componentPath] = true; $componentNamespace = $namespace . '\\' . $componentName; $componentFile = $componentPath . DIRECTORY_SEPARATOR . $componentName . $ext; @@ -178,7 +187,7 @@ protected function scanForComponents(string $path, string $ext, string $namespac // Continue recursively $components = array_merge( $components, - $this->scanForComponents($componentPath, $ext, $componentNamespace) + $this->scanForComponents($componentPath, $ext, $componentNamespace, $scannedPaths) ); } diff --git a/Tests/Fixtures/ComponentLoader/Atom/ComponentLoaderSymlink b/Tests/Fixtures/ComponentLoader/Atom/ComponentLoaderSymlink new file mode 120000 index 0000000..93df1d4 --- /dev/null +++ b/Tests/Fixtures/ComponentLoader/Atom/ComponentLoaderSymlink @@ -0,0 +1 @@ +../../ComponentLoaderSymlink/ \ No newline at end of file diff --git a/Tests/Fixtures/ComponentLoader/Molecule/Circular b/Tests/Fixtures/ComponentLoader/Molecule/Circular new file mode 120000 index 0000000..b870225 --- /dev/null +++ b/Tests/Fixtures/ComponentLoader/Molecule/Circular @@ -0,0 +1 @@ +../ \ No newline at end of file diff --git a/Tests/Fixtures/ComponentLoader/Molecule/Example b/Tests/Fixtures/ComponentLoader/Molecule/Example new file mode 120000 index 0000000..6b784d7 --- /dev/null +++ b/Tests/Fixtures/ComponentLoader/Molecule/Example @@ -0,0 +1 @@ +../Example/ \ No newline at end of file diff --git a/Tests/Fixtures/ComponentLoaderSymlink/ComponentLoaderSymlink.html b/Tests/Fixtures/ComponentLoaderSymlink/ComponentLoaderSymlink.html new file mode 100644 index 0000000..e69de29 diff --git a/Tests/Unit/ComponentLoaderTest.php b/Tests/Unit/ComponentLoaderTest.php index 1090345..2ee8604 100644 --- a/Tests/Unit/ComponentLoaderTest.php +++ b/Tests/Unit/ComponentLoaderTest.php @@ -15,7 +15,7 @@ protected function setUp() protected function getFixturePath($fixtureName) { - return dirname(__FILE__) . '/../Fixtures/' . $fixtureName; + return realpath(dirname(__FILE__) . '/../Fixtures/' . $fixtureName); } public function addNamespaceProvider() @@ -177,6 +177,7 @@ public function findComponentsInNamespaceProvider() '.html', [ 'Sitegeist\\Fixtures\\ComponentLoader\\Atom\\Button' => $this->getFixturePath('ComponentLoader/Atom/Button/Button.html'), + 'Sitegeist\\Fixtures\\ComponentLoader\\Atom\\ComponentLoaderSymlink' => $this->getFixturePath('ComponentLoader/Atom/ComponentLoaderSymlink/ComponentLoaderSymlink.html'), 'Sitegeist\\Fixtures\\ComponentLoader\\Atom\\Link' => $this->getFixturePath('ComponentLoader/Atom/Link/Link.html'), 'Sitegeist\\Fixtures\\ComponentLoader\\Example' => $this->getFixturePath('ComponentLoader/Example/Example.html'), 'Sitegeist\\Fixtures\\ComponentLoader\\Molecule\\Teaser' => $this->getFixturePath('ComponentLoader/Molecule/Teaser/Teaser.html'),