[TASK] Ignore test class names and class paths 66/40966/5
authorHelmut Hummel <helmut.hummel@typo3.org>
Tue, 7 Jul 2015 16:14:05 +0000 (18:14 +0200)
committerGeorg Ringer <georg.ringer@gmail.com>
Thu, 16 Jul 2015 09:22:29 +0000 (11:22 +0200)
For class map generation in non composer mode,
ignore some folders and class names.

Releases: 7.3, master
Resolves: #67763
Change-Id: Ided9a668a025ffd7371210ac955b278e080980d7
Reviewed-on: http://review.typo3.org/40966
Reviewed-by: Nicole Cordes <typo3@cordes.co>
Tested-by: Nicole Cordes <typo3@cordes.co>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
typo3/sysext/core/Classes/Core/ClassLoadingInformation.php
typo3/sysext/core/Classes/Core/ClassLoadingInformationGenerator.php
typo3/sysext/core/Tests/Unit/Core/ClassLoadingInformationGeneratorTest.php [new file with mode: 0644]

index 705bfe6..d1d8a4f 100644 (file)
@@ -64,11 +64,13 @@ class ClassLoadingInformation {
         */
        static public function writeClassLoadingInformation() {
                self::ensureAutoloadInfoDirExists();
-               $classInfoFiles = ClassLoadingInformationGenerator::buildAutoloadInformationFiles();
+               /** @var ClassLoadingInformationGenerator  $generator */
+               $generator = GeneralUtility::makeInstance(ClassLoadingInformationGenerator::class);
+               $classInfoFiles = $generator->buildAutoloadInformationFiles();
                GeneralUtility::writeFile(PATH_site . self::AUTOLOAD_INFO_DIR . self::AUTOLOAD_CLASSMAP_FILENAME, $classInfoFiles['classMapFile']);
                GeneralUtility::writeFile(PATH_site . self::AUTOLOAD_INFO_DIR . self::AUTOLOAD_PSR4_FILENAME, $classInfoFiles['psr-4File']);
 
-               $classAliasMapFile = ClassLoadingInformationGenerator::buildClassAliasMapFile();
+               $classAliasMapFile = $generator->buildClassAliasMapFile();
                GeneralUtility::writeFile(PATH_site . self::AUTOLOAD_INFO_DIR . self::AUTOLOAD_CLASSALIASMAP_FILENAME, $classAliasMapFile);
        }
 
@@ -114,12 +116,16 @@ class ClassLoadingInformation {
         */
        static public function registerTransientClassLoadingInformationForPackage(PackageInterface $package) {
                $composerClassLoader = static::getClassLoader();
-               $classInformation = ClassLoadingInformationGenerator::buildClassLoadingInformationForPackage($package);
+
+               /** @var ClassLoadingInformationGenerator  $generator */
+               $generator = GeneralUtility::makeInstance(ClassLoadingInformationGenerator::class);
+
+               $classInformation = $generator->buildClassLoadingInformationForPackage($package);
                $composerClassLoader->addClassMap($classInformation['classMap']);
                foreach ($classInformation['psr-4'] as $prefix => $paths) {
                        $composerClassLoader->setPsr4($prefix, $paths);
                }
-               $classAliasMap = ClassLoadingInformationGenerator::buildClassAliasMapForPackage($package);
+               $classAliasMap = $generator->buildClassAliasMapForPackage($package);
                if (is_array($classAliasMap) && !empty($classAliasMap['aliasToClassNameMapping']) && !empty($classAliasMap['classNameToAliasMapping'])) {
                        self::getClassAliasLoader($composerClassLoader)->addAliasMap($classAliasMap);
                }
index 14b03d3..8954adb 100644 (file)
@@ -39,7 +39,7 @@ class ClassLoadingInformationGenerator {
         * @param bool $useRelativePaths If set to TRUE, make the path relative to the current TYPO3 instance (PATH_site)
         * @return array
         */
-       static public function buildClassLoadingInformationForPackage(PackageInterface $package, $useRelativePaths = FALSE) {
+       public function buildClassLoadingInformationForPackage(PackageInterface $package, $useRelativePaths = FALSE) {
                $classMap = array();
                $psr4 = array();
                $packagePath = $package->getPackagePath();
@@ -52,7 +52,7 @@ class ClassLoadingInformationGenerator {
                                        foreach ($psr4manifest as $namespacePrefix => $path) {
                                                $namespacePath = $packagePath . $path;
                                                if ($useRelativePaths) {
-                                                       $psr4[$namespacePrefix] = self::makePathRelative($namespacePath, realpath($namespacePath));
+                                                       $psr4[$namespacePrefix] = $this->makePathRelative($namespacePath, realpath($namespacePath));
                                                } else {
                                                        $psr4[$namespacePrefix] = $namespacePath;
                                                }
@@ -64,6 +64,12 @@ class ClassLoadingInformationGenerator {
                }
 
                foreach (ClassMapGenerator::createMap($packagePath) as $class => $path) {
+                       if ($this->isIgnoredPath($packagePath, $path)) {
+                               continue;
+                       }
+                       if ($this->isIgnoredClassName($class)) {
+                               continue;
+                       }
                        if ($useRelativePaths) {
                                $classMap[$class] = self::makePathRelative($packagePath, $path);
                        } else {
@@ -75,13 +81,45 @@ class ClassLoadingInformationGenerator {
        }
 
        /**
+        * Check if the class path should be ignored.
+        * Currently only tests folders are ignored.
+        *
+        * @param string $packagePath
+        * @param string $path
+        * @return bool
+        */
+       protected function isIgnoredPath($packagePath, $path) {
+               if (stripos($this->makePathRelative($packagePath, $path, FALSE), 'tests') !== FALSE) {
+                       return TRUE;
+               }
+
+               return FALSE;
+       }
+
+       /**
+        * Check if class name should be ignored.
+        * Currently all classes with suffix "Test" and "Fixture" will be ignored
+        *
+        * @param string $className
+        * @return bool
+        */
+       protected function isIgnoredClassName($className) {
+               foreach (array('test', 'fixture') as $suffix) {
+                       if (strtolower(substr($className, 0 - strlen($suffix))) === $suffix) {
+                               return TRUE;
+                       }
+               }
+               return FALSE;
+       }
+
+       /**
         * Returns class alias map for given package
         *
         * @param PackageInterface $package The package to generate the class alias info for
         * @throws \TYPO3\CMS\Core\Error\Exception
         * @return array
         */
-       static public function buildClassAliasMapForPackage(PackageInterface $package) {
+       public function buildClassAliasMapForPackage(PackageInterface $package) {
                $aliasToClassNameMapping = array();
                $classNameToAliasMapping = array();
                $possibleClassAliasFile = $package->getPackagePath() . 'Migrations/Code/ClassAliasMap.php';
@@ -105,7 +143,7 @@ class ClassLoadingInformationGenerator {
         * @return string[]
         * @internal
         */
-       static public function buildAutoloadInformationFiles() {
+       public function buildAutoloadInformationFiles() {
                // Ensure that for each re-build, the packages are fetched again from the package manager
                self::$activeExtensionPackages = NULL;
 
@@ -121,7 +159,7 @@ return array(
 EOF;
                $classMap = array();
                $psr4 = array();
-               foreach (self::getActiveExtensionPackages() as $package) {
+               foreach ($this->getActiveExtensionPackages() as $package) {
                        $classLoadingInformation = self::buildClassLoadingInformationForPackage($package, TRUE);
                        $classMap = array_merge($classMap, $classLoadingInformation['classMap']);
                        $psr4 = array_merge($psr4, $classLoadingInformation['psr-4']);
@@ -147,13 +185,18 @@ EOF;
         *
         * @param string $packagePath
         * @param string $realPathOfClassFile
+        * @param bool $relativeToRoot
         * @return string
         */
-       static protected function makePathRelative($packagePath, $realPathOfClassFile) {
+       protected function makePathRelative($packagePath, $realPathOfClassFile, $relativeToRoot = TRUE) {
                $realPathOfClassFile = GeneralUtility::fixWindowsFilePath($realPathOfClassFile);
-               $classesRealPath = GeneralUtility::fixWindowsFilePath(realpath($packagePath));
-               $relativeClassesPath = rtrim(PathUtility::stripPathSitePrefix($packagePath), '/');
-               $relativePathToClassFile = $relativeClassesPath . '/' . ltrim(substr($realPathOfClassFile, strlen($classesRealPath)), '/');
+               $packageRealPath = GeneralUtility::fixWindowsFilePath(realpath($packagePath));
+               $relativePackagePath = rtrim(PathUtility::stripPathSitePrefix($packagePath), '/');
+               if ($relativeToRoot) {
+                       $relativePathToClassFile = $relativePackagePath . '/' . ltrim(substr($realPathOfClassFile, strlen($packageRealPath)), '/');
+               } else {
+                       $relativePathToClassFile = ltrim(substr($realPathOfClassFile, strlen($packageRealPath)), '/');
+               }
 
                return $relativePathToClassFile;
        }
@@ -164,7 +207,7 @@ EOF;
         * @param string $relativePathToClassFile
         * @return string
         */
-       static protected function getPathCode($relativePathToClassFile) {
+       protected function getPathCode($relativePathToClassFile) {
                return '$typo3InstallDir . ' . var_export($relativePathToClassFile, TRUE);
        }
 
@@ -175,7 +218,7 @@ EOF;
         * @throws \Exception
         * @internal
         */
-       static public function buildClassAliasMapFile() {
+       public function buildClassAliasMapFile() {
                $aliasToClassNameMapping = array();
                $classNameToAliasMapping = array();
                foreach (self::getActiveExtensionPackages() as $package) {
@@ -198,7 +241,7 @@ EOF;
         *
         * @return PackageInterface[]
         */
-       static protected function getActiveExtensionPackages() {
+       protected function getActiveExtensionPackages() {
                if (self::$activeExtensionPackages === NULL) {
                        self::$activeExtensionPackages = array();
                        foreach (self::getPackageManager()->getActivePackages() as $package) {
@@ -219,7 +262,7 @@ EOF;
         * @param PackageInterface $package
         * @return bool
         */
-       static protected function isFrameworkPackage(PackageInterface $package) {
+       protected function isFrameworkPackage(PackageInterface $package) {
                return $package->getValueFromComposerManifest('type') === 'typo3-cms-framework';
        }
 
@@ -227,7 +270,7 @@ EOF;
         * @return PackageManager
         * @throws \TYPO3\CMS\Core\Exception
         */
-       static protected function getPackageManager() {
+       protected function getPackageManager() {
                return Bootstrap::getInstance()->getEarlyInstance(PackageManager::class);
        }
 
diff --git a/typo3/sysext/core/Tests/Unit/Core/ClassLoadingInformationGeneratorTest.php b/typo3/sysext/core/Tests/Unit/Core/ClassLoadingInformationGeneratorTest.php
new file mode 100644 (file)
index 0000000..c506c74
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+namespace TYPO3\CMS\Core\Tests\Unit\Core;
+
+/*                                                                        *
+ * This script belongs to the TYPO3 Flow framework.                       *
+ *                                                                        *
+ * It is free software; you can redistribute it and/or modify it under    *
+ * the terms of the GNU Lesser General Public License, either version 3   *
+ * of the License, or (at your option) any later version.                 *
+ *                                                                        *
+ * The TYPO3 project - inspiring people to share!                         *
+ *                                                                        */
+use TYPO3\CMS\Core\Core\ClassLoadingInformationGenerator;
+use TYPO3\CMS\Core\Tests\UnitTestCase;
+
+
+/**
+ * Testcase for the ClassLoadingInformationGenerator class
+ */
+class ClassLoadingInformationGeneratorTest extends UnitTestCase {
+
+       /**
+        * Data provider with different class names.
+        *
+        * @return array
+        */
+       public function isIgnoredClassNameIgnoresTestClassesDataProvider() {
+               return array(
+                       array('FoTest', TRUE),
+                       array('FoLowercasetest', TRUE),
+                       array('DifferentClassTes', FALSE),
+                       array('Test', TRUE),
+                       array('FoFixture', TRUE),
+                       array('FoLowercasefixture', TRUE),
+                       array('DifferentClassFixtur', FALSE),
+                       array('Fixture', TRUE),
+               );
+       }
+
+       /**
+        * @test
+        * @dataProvider isIgnoredClassNameIgnoresTestClassesDataProvider
+        */
+       public function isIgnoredClassNameIgnoresTestClasses($path, $expectedResult) {
+               $generator = $this->getAccessibleMock(ClassLoadingInformationGenerator::class, ['dummy']);
+
+               $this->assertEquals($expectedResult, $generator->_call('isIgnoredClassName', $path));
+       }
+
+}