diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..4283b9a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,64 @@ +name: CI + +on: [push, pull_request] + +jobs: + testsuite: + + runs-on: ubuntu-latest + strategy: + matrix: + TYPO3: [ '11' , '12', '13'] + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Set up PHP Version + uses: shivammathur/setup-php@v2 + with: + php-version: 8.1 + tools: composer:v2 + + - name: Start MySQL + run: sudo /etc/init.d/mysql start + + - name: Validate composer.json and composer.lock + run: composer validate + + - name: Cache dependencies + uses: actions/cache@v1 + with: + path: ~/.composer/cache + key: dependencies-composer-${{ hashFiles('composer.json') }} + + - name: Install composer dependencies TYPO3 13 + if: matrix.TYPO3 == '13' + run: | + composer install --no-progress --no-interaction + + - name: Install composer dependencies TYPO3 12 + if: matrix.TYPO3 == '12' + run: | + composer require typo3/cms-core:^12.4 --no-progress --no-interaction --dev -W + - name: Install composer dependencies TYPO3 11 + if: matrix.TYPO3 == '11' + run: | + composer require typo3/cms-core:^11.5 --no-progress --no-interaction --dev -W + - name: Phpstan 12/13 + if: matrix.TYPO3 != '11' + run: .Build/bin/phpstan analyze -c Build/phpstan.neon + - name: Phpstan 11 + if: matrix.TYPO3 == '11' + run: .Build/bin/phpstan analyze -c Build/phpstan11.neon + - name: Phpcsfix + run: .Build/bin/php-cs-fixer fix --config=Build/php-cs-fixer.php --dry-run --stop-on-violation --using-cache=no + - name: Unit Tests + run: .Build/bin/phpunit -c Build/phpunit/UnitTests.xml Tests/Unit + - name: Functional Tests + run: | + export typo3DatabaseName="typo3"; + export typo3DatabaseHost="127.0.0.1"; + export typo3DatabaseUsername="root"; + export typo3DatabasePassword="root"; + .Build/bin/phpunit -c Build/phpunit/FunctionalTests.xml Tests/Functional diff --git a/.gitignore b/.gitignore index a1ee133..ebbd882 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -/build/ /composer.lock -/.php_cs.cache -/public/ \ No newline at end of file +/Build/phpunit/.phpunit.* +/public/ +/.Build/ diff --git a/Build/php-cs-fixer.php b/Build/php-cs-fixer.php new file mode 100644 index 0000000..6ee0307 --- /dev/null +++ b/Build/php-cs-fixer.php @@ -0,0 +1,5 @@ +getFinder()->exclude(['var'])->in(__DIR__ . '/..'); +return $config; diff --git a/Build/phpstan.neon b/Build/phpstan.neon new file mode 100644 index 0000000..457f990 --- /dev/null +++ b/Build/phpstan.neon @@ -0,0 +1,6 @@ +includes: + - ../.Build/vendor/saschaegerer/phpstan-typo3/extension.neon +parameters: + level: 5 + paths: + - %currentWorkingDirectory%/Classes \ No newline at end of file diff --git a/Build/phpstan11.neon b/Build/phpstan11.neon new file mode 100644 index 0000000..649a756 --- /dev/null +++ b/Build/phpstan11.neon @@ -0,0 +1,8 @@ +includes: + - ../.Build/vendor/saschaegerer/phpstan-typo3/extension.neon +parameters: + level: 5 + paths: + - %currentWorkingDirectory%/Classes + excludePaths: + - %currentWorkingDirectory%/Classes/Listener/AfterCacheableContentIsGenerated.php diff --git a/Build/phpunit/FunctionalTests.xml b/Build/phpunit/FunctionalTests.xml new file mode 100644 index 0000000..3c32aa4 --- /dev/null +++ b/Build/phpunit/FunctionalTests.xml @@ -0,0 +1,12 @@ + + + + + ../../Tests/Functional/ + + + + + + + diff --git a/Build/phpunit/FunctionalTestsBootstrap.php b/Build/phpunit/FunctionalTestsBootstrap.php new file mode 100644 index 0000000..443197d --- /dev/null +++ b/Build/phpunit/FunctionalTestsBootstrap.php @@ -0,0 +1,20 @@ +defineOriginalRootPath(); + $testbase->createDirectory(ORIGINAL_ROOT . 'typo3temp/var/tests'); + $testbase->createDirectory(ORIGINAL_ROOT . 'typo3temp/var/transient'); +}); diff --git a/Build/phpunit/UnitTests.xml b/Build/phpunit/UnitTests.xml new file mode 100644 index 0000000..380f48d --- /dev/null +++ b/Build/phpunit/UnitTests.xml @@ -0,0 +1,12 @@ + + + + + ../../Tests/Unit/ + + + + + + + diff --git a/Build/phpunit/UnitTestsBootstrap.php b/Build/phpunit/UnitTestsBootstrap.php new file mode 100644 index 0000000..b12ccf0 --- /dev/null +++ b/Build/phpunit/UnitTestsBootstrap.php @@ -0,0 +1,74 @@ +getWebRoot(), '/')); + } + if (!getenv('TYPO3_PATH_WEB')) { + putenv('TYPO3_PATH_WEB=' . rtrim($testbase->getWebRoot(), '/')); + } + + $testbase->defineSitePath(); + + $requestType = \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::REQUESTTYPE_BE | \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::REQUESTTYPE_CLI; + \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::run(0, $requestType); + + $testbase->createDirectory(\TYPO3\CMS\Core\Core\Environment::getPublicPath() . '/typo3conf/ext'); + $testbase->createDirectory(\TYPO3\CMS\Core\Core\Environment::getPublicPath() . '/typo3temp/assets'); + $testbase->createDirectory(\TYPO3\CMS\Core\Core\Environment::getPublicPath() . '/typo3temp/var/tests'); + $testbase->createDirectory(\TYPO3\CMS\Core\Core\Environment::getPublicPath() . '/typo3temp/var/transient'); + + // Retrieve an instance of class loader and inject to core bootstrap + $classLoader = require $testbase->getPackagesPath() . '/autoload.php'; + \TYPO3\CMS\Core\Core\Bootstrap::initializeClassLoader($classLoader); + + // Initialize default TYPO3_CONF_VARS + $configurationManager = new \TYPO3\CMS\Core\Configuration\ConfigurationManager(); + $GLOBALS['TYPO3_CONF_VARS'] = $configurationManager->getDefaultConfiguration(); + + $cache = new \TYPO3\CMS\Core\Cache\Frontend\PhpFrontend( + 'core', + new \TYPO3\CMS\Core\Cache\Backend\NullBackend('production', []) + ); + // Set all packages to active + if (version_compare((new Typo3Version())->getVersion(), '11.3.0', '>')) { + $packageManager = \TYPO3\CMS\Core\Core\Bootstrap::createPackageManager( + \TYPO3\CMS\Core\Package\UnitTestPackageManager::class, + \TYPO3\CMS\Core\Core\Bootstrap::createPackageCache($cache) + ); + } else { + $packageManager = \TYPO3\CMS\Core\Core\Bootstrap::createPackageManager( + \TYPO3\CMS\Core\Package\UnitTestPackageManager::class, + $cache + ); + } + \TYPO3\CMS\Core\Utility\GeneralUtility::setSingletonInstance(\TYPO3\CMS\Core\Package\PackageManager::class, $packageManager); + \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::setPackageManager($packageManager); + + $testbase->dumpClassLoadingInformation(); + + \TYPO3\CMS\Core\Utility\GeneralUtility::purgeInstances(); +}); diff --git a/Classes/AssetCollector.php b/Classes/AssetCollector.php index 770730f..880d9df 100644 --- a/Classes/AssetCollector.php +++ b/Classes/AssetCollector.php @@ -1,6 +1,7 @@ removeUtf8Bom(file_get_contents($absoluteFile)); @@ -183,7 +185,7 @@ public function buildJavaScriptIncludes(): string $attributeCode[] = htmlspecialchars($name); } } - $webPath = (strpos($file['fileName'], 'EXT:') === 0) + $webPath = (str_starts_with($file['fileName'], 'EXT:')) ? PathUtility::getAbsoluteWebPath(GeneralUtility::getFileAbsFileName(($file['fileName']))) : $file['fileName']; $includes .= ''; diff --git a/Classes/Hooks/AssetRenderer.php b/Classes/Hooks/AssetRenderer.php index 96b7d60..a98d87a 100644 --- a/Classes/Hooks/AssetRenderer.php +++ b/Classes/Hooks/AssetRenderer.php @@ -1,6 +1,7 @@ getBody(); $body->rewind(); $contents = $response->getBody()->getContents(); - if (strpos($contents, '') !== false) { + if (str_contains($contents, '')) { $content = str_ireplace( '', $svgAsset . '', diff --git a/Classes/Resource/ResourceCompressor.php b/Classes/Resource/ResourceCompressor.php index 7be6119..914625d 100644 --- a/Classes/Resource/ResourceCompressor.php +++ b/Classes/Resource/ResourceCompressor.php @@ -1,6 +1,7 @@ 'typo3conf/sites']; - - protected function executeFrontendRequestWrapper(InternalRequest $request, InternalRequestContext $context = null, bool $followRedirects = false): ResponseInterface - { - if ((GeneralUtility::makeInstance(Typo3Version::class))->getMajorVersion() < 11) { - return $this->executeFrontendRequest($request, $context, $followRedirects); - } - return $this->executeFrontendSubRequest($request, $context, $followRedirects); - } -} diff --git a/Tests/Functional/Frontend/InlineCssTest.php b/Tests/Functional/Frontend/InlineCssTest.php index 812ba32..96da362 100644 --- a/Tests/Functional/Frontend/InlineCssTest.php +++ b/Tests/Functional/Frontend/InlineCssTest.php @@ -11,16 +11,21 @@ */ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; +use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; -class InlineCssTest extends AbstractFrontendTest +class InlineCssTest extends FunctionalTestCase { + protected array $testExtensionsToLoad = ['typo3conf/ext/assetcollector']; + protected array $coreExtensionsToLoad = ['core', 'frontend']; + protected array $pathsToLinkInTestInstance = ['typo3conf/ext/assetcollector/Build/sites' => 'typo3conf/sites']; + /** * @test */ public function scriptTagForInlineCssIsRendered(): void { - $this->importCSVDataSet(ORIGINAL_ROOT . 'typo3conf/ext/assetcollector/Tests/Functional/Frontend/Fixtures/inline_css.csv'); - $response = $this->executeFrontendRequestWrapper(new InternalRequest('http://localhost/')); + $this->importCSVDataSet(__DIR__ . '/Fixtures/inline_css.csv'); + $response = $this->executeFrontendSubRequest(new InternalRequest('http://localhost/')); $expected = '