From 2ce48affb72bc929a9b6a7432f53039ff9a67c99 Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Mon, 21 Oct 2024 10:09:55 +0200 Subject: [PATCH 01/13] [BUGFIX] Fixed Type Error when cObj returns null - Implemented `getContentObjectRenderer()` method to handle cases where `cObj` might be null in some cases where request is not build completely - Adjusted `applyStdWrapProperties()` to ensure graceful fallback when `cObj` is not available. This improves error handling and diagnostics, making the extension more reliable and easier to maintain. Resolves: #37 --- Classes/Helper/TypoScriptHelper.php | 7 ++++++- Classes/Traits/GetTypoScriptFrontendControllerTrait.php | 8 +++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Classes/Helper/TypoScriptHelper.php b/Classes/Helper/TypoScriptHelper.php index ff9ca46..2aed77a 100644 --- a/Classes/Helper/TypoScriptHelper.php +++ b/Classes/Helper/TypoScriptHelper.php @@ -102,6 +102,11 @@ public function hasReplaceEntry(array $typoScriptConfiguration, $key): bool public function applyStdWrapProperties(string $content, array $stdWrapConfiguration): string { - return $this->getContentObjectRenderer()->stdWrap($content, $stdWrapConfiguration); + $contentObjectRenderer = $this->getContentObjectRenderer(); + if ($contentObjectRenderer === null) { + return $content; + } + + return $contentObjectRenderer->stdWrap($content, $stdWrapConfiguration); } } diff --git a/Classes/Traits/GetTypoScriptFrontendControllerTrait.php b/Classes/Traits/GetTypoScriptFrontendControllerTrait.php index 021f1ce..5ffacec 100644 --- a/Classes/Traits/GetTypoScriptFrontendControllerTrait.php +++ b/Classes/Traits/GetTypoScriptFrontendControllerTrait.php @@ -31,6 +31,12 @@ protected function getTypoScriptFrontendController(): TypoScriptFrontendControll protected function getContentObjectRenderer(): ?ContentObjectRenderer { - return $this->getTypoScriptFrontendController()->cObj; + $tsfe = $this->getTypoScriptFrontendController(); + + if (!$tsfe->cObj) { + return null; + } + + return $tsfe->cObj; } } From 7b16b96cad2ce7c685b27201c15929cc5708e485 Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Mon, 21 Oct 2024 10:42:34 +0200 Subject: [PATCH 02/13] [TASK] Formatting Lint and CGL mostly commas in arrays --- .../workflows/{testscorev12.yml => ci.yml} | 0 .github/workflows/testscorev11.yml | 53 --- Build/FunctionalTests.xml | 28 -- Build/FunctionalTestsBootstrap.php | 17 - Build/Scripts/runTests.sh | 395 ----------------- Build/UnitTests.xml | 29 -- Build/UnitTestsBootstrap.php | 75 ---- Build/php-cs-fixer/config.php | 94 ----- Build/testing-docker/docker-compose.yml | 398 ------------------ .../ReplaceConfigurationTest.php | 12 +- .../ConfigurationTypeEnumerationTest.php | 6 +- .../ReplaceContentCachedTest.php | 12 +- .../ReplaceContentUnCachedTest.php | 12 +- .../Functional/Helper/ReplacerHelperTest.php | 2 +- .../Helper/TypoScriptHelperTest.php | 52 +-- .../TypoScriptFrontendControllerHookTest.php | 4 +- .../ReplaceContentMiddlewareTest.php | 4 +- 17 files changed, 52 insertions(+), 1141 deletions(-) rename .github/workflows/{testscorev12.yml => ci.yml} (100%) delete mode 100644 .github/workflows/testscorev11.yml delete mode 100644 Build/FunctionalTests.xml delete mode 100644 Build/FunctionalTestsBootstrap.php delete mode 100755 Build/Scripts/runTests.sh delete mode 100644 Build/UnitTests.xml delete mode 100644 Build/UnitTestsBootstrap.php delete mode 100644 Build/php-cs-fixer/config.php delete mode 100644 Build/testing-docker/docker-compose.yml diff --git a/.github/workflows/testscorev12.yml b/.github/workflows/ci.yml similarity index 100% rename from .github/workflows/testscorev12.yml rename to .github/workflows/ci.yml diff --git a/.github/workflows/testscorev11.yml b/.github/workflows/testscorev11.yml deleted file mode 100644 index 5a5c8ca..0000000 --- a/.github/workflows/testscorev11.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Test replacer for TYPO3 11 LTS - -on: - pull_request: - -jobs: - CGL: - name: Coding Style Check (TYPO3 Community CGL) - - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Composer - run: Build/Scripts/runTests.sh -t 11 -p 8.1 -s composerUpdate - - - name: Lint PHP - run: Build/Scripts/runTests.sh -t 11 -p 8.1 -s lint - - - name: Validate code against CGL - run: Build/Scripts/runTests.sh -t 11 -p 8.1 -s cgl -n - - testsuite: - name: PHP Unit and Functional Tests for TYPO3 Version 11 LTS - - needs: CGL - - runs-on: ubuntu-latest - - strategy: - matrix: - php: [ '7.4', '8.0', '8.1', '8.2' ] - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Composer - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -t 11 -s composerUpdate - - - name: Lint PHP - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s lint - - - name: Functional tests with mariadb - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -d mariadb -s functional - - - name: Functional tests with postgres - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -d postgres -s functional - - - name: Functional tests with sqlite - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -d sqlite -s functional diff --git a/Build/FunctionalTests.xml b/Build/FunctionalTests.xml deleted file mode 100644 index 59a41b6..0000000 --- a/Build/FunctionalTests.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - ../Tests/Functional/ - - - - - - - diff --git a/Build/FunctionalTestsBootstrap.php b/Build/FunctionalTestsBootstrap.php deleted file mode 100644 index 52db699..0000000 --- a/Build/FunctionalTestsBootstrap.php +++ /dev/null @@ -1,17 +0,0 @@ -defineOriginalRootPath(); - $testbase->createDirectory(ORIGINAL_ROOT . 'typo3temp/var/tests'); - $testbase->createDirectory(ORIGINAL_ROOT . 'typo3temp/var/transient'); -}); diff --git a/Build/Scripts/runTests.sh b/Build/Scripts/runTests.sh deleted file mode 100755 index 8881707..0000000 --- a/Build/Scripts/runTests.sh +++ /dev/null @@ -1,395 +0,0 @@ -#!/usr/bin/env bash - -# -# TYPO3 core test runner based on docker and docker-compose. -# - -# Function to write a .env file in Build/testing-docker -# This is read by docker-compose and vars defined here are -# used in Build/testing-docker/docker-compose.yml -setUpDockerComposeDotEnv() { - # Delete possibly existing local .env file if exists - [ -e .env ] && rm .env - # Set up a new .env file for docker-compose - { - echo "COMPOSE_PROJECT_NAME=local" - # To prevent access rights of files created by the testing, the docker image later - # runs with the same user that is currently executing the script. docker-compose can't - # use $UID directly itself since it is a shell variable and not an env variable, so - # we have to set it explicitly here. - echo "HOST_UID=`id -u`" - # Your local user - echo "ROOT_DIR=${ROOT_DIR}" - echo "HOST_USER=${USER}" - echo "TEST_FILE=${TEST_FILE}" - echo "TYPO3_VERSION=${TYPO3_VERSION}" - echo "PHP_XDEBUG_ON=${PHP_XDEBUG_ON}" - echo "PHP_XDEBUG_PORT=${PHP_XDEBUG_PORT}" - echo "DOCKER_PHP_IMAGE=${DOCKER_PHP_IMAGE}" - echo "EXTRA_TEST_OPTIONS=${EXTRA_TEST_OPTIONS}" - echo "SCRIPT_VERBOSE=${SCRIPT_VERBOSE}" - echo "CGLCHECK_DRY_RUN=${CGLCHECK_DRY_RUN}" - echo "DATABASE_DRIVER=${DATABASE_DRIVER}" - } > .env -} - -# Options -a and -d depend on each other. The function -# validates input combinations and sets defaults. -handleDbmsAndDriverOptions() { - case ${DBMS} in - mysql|mariadb) - [ -z "${DATABASE_DRIVER}" ] && DATABASE_DRIVER="mysqli" - if [ "${DATABASE_DRIVER}" != "mysqli" ] && [ "${DATABASE_DRIVER}" != "pdo_mysql" ]; then - echo "Invalid option -a ${DATABASE_DRIVER} with -d ${DBMS}" >&2 - echo >&2 - echo "call \"./Build/Scripts/runTests.sh -h\" to display help and valid options" >&2 - exit 1 - fi - ;; - postgres|sqlite) - if [ -n "${DATABASE_DRIVER}" ]; then - echo "Invalid option -a ${DATABASE_DRIVER} with -d ${DBMS}" >&2 - echo >&2 - echo "call \"./Build/Scripts/runTests.sh -h\" to display help and valid options" >&2 - exit 1 - fi - ;; - esac -} - -# Load help text into $HELP -read -r -d '' HELP <=20.10 for xdebug break pointing to work reliably, and -a recent docker-compose (tested >=1.21.2) is needed. - -Usage: $0 [options] [file] - -No arguments: Run all unit tests with PHP 8.1 - -Options: - -s <...> - Specifies which test suite to run - - acceptance: backend acceptance tests - - cgl: cgl test and fix all php files - - clean: clean up build and testing related files - - composerUpdate: "composer update", handy if host has no PHP - - functional: functional tests - - lint: PHP linting - - phpstan: phpstan analyze - - phpstanGenerateBaseline: regenerate phpstan baseline, handy after phpstan updates - - unit (default): PHP unit tests - - -a - Only with -s acceptance,functional - Specifies to use another driver, following combinations are available: - - mysql - - mysqli (default) - - pdo_mysql - - mariadb - - mysqli (default) - - pdo_mysql - - -d - Only with -s acceptance,functional - Specifies on which DBMS tests are performed - - sqlite: (default) use sqlite - - mariadb: use mariadb - - mysql: use mysql - - postgres: use postgres - - - -p <7.4|8.0|8.1|8.2> - Specifies the PHP minor version to be used - - 7.4 (default): use PHP 7.4 - - 8.0: use PHP 8.0 - - 8.1: use PHP 8.1 - - 8.2: use PHP 8.2 - - -t <11|12> - Only with -s composerUpdate - Specifies the TYPO3 core major version to be used - - 11 (default): use TYPO3 core v11 - - 12: Use TYPO3 core v12 - - -e "" - Only with -s acceptance|functional|unit - Additional options to send to phpunit (unit & functional tests) or codeception (acceptance - tests). For phpunit, options starting with "--" must be added after options starting with "-". - Example -e "-v --filter canRetrieveValueWithGP" to enable verbose output AND filter tests - named "canRetrieveValueWithGP" - - -x - Only with -s functional|unit|acceptance - Send information to host instance for test or system under test break points. This is especially - useful if a local PhpStorm instance is listening on default xdebug port 9003. A different port - can be selected with -y - - -n - Only with -s cgl - Activate dry-run in CGL check that does not actively change files and only prints broken ones. - - -u - Update existing typo3/core-testing-*:latest docker images. Maintenance call to docker pull latest - versions of the main php images. The images are updated once in a while and only the youngest - ones are supported by core testing. Use this if weird test errors occur. Also removes obsolete - image versions of typo3/core-testing-*. - - -v - Enable verbose script output. Shows variables and docker commands. - - -h - Show this help. - -Examples: - # Run unit tests using PHP 7.4 - ./Build/Scripts/runTests.sh -EOF - -# Test if docker-compose exists, else exit out with error -if ! type "docker-compose" > /dev/null; then - echo "This script relies on docker and docker-compose. Please install" >&2 - exit 1 -fi - -# Go to the directory this script is located, so everything else is relative -# to this dir, no matter from where this script is called. -THIS_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" -cd "$THIS_SCRIPT_DIR" || exit 1 - -# Go to directory that contains the local docker-compose.yml file -cd ../testing-docker || exit 1 - -# Option defaults -if ! command -v realpath &> /dev/null; then - echo "This script works best with realpath installed" >&2 - ROOT_DIR="${PWD}/../../" -else - ROOT_DIR=`realpath ${PWD}/../../` -fi -TEST_SUITE="unit" -DBMS="sqlite" -PHP_VERSION="7.4" -TYPO3_VERSION="11" -PHP_XDEBUG_ON=0 -PHP_XDEBUG_PORT=9003 -EXTRA_TEST_OPTIONS="" -SCRIPT_VERBOSE=0 -CGLCHECK_DRY_RUN="" -DATABASE_DRIVER="" - -# Option parsing -# Reset in case getopts has been used previously in the shell -OPTIND=1 -# Array for invalid options -INVALID_OPTIONS=(); -# Simple option parsing based on getopts (! not getopt) -while getopts ":s:a:d:p:t:e:xnhuv" OPT; do - case ${OPT} in - s) - TEST_SUITE=${OPTARG} - ;; - a) - DATABASE_DRIVER=${OPTARG} - ;; - d) - DBMS=${OPTARG} - ;; - p) - PHP_VERSION=${OPTARG} - if ! [[ ${PHP_VERSION} =~ ^(7.4|8.0|8.1|8.2)$ ]]; then - INVALID_OPTIONS+=("p ${OPTARG}") - fi - ;; - t) - TYPO3_VERSION=${OPTARG} - if ! [[ ${TYPO3_VERSION} =~ ^(11|12)$ ]]; then - INVALID_OPTIONS+=("p ${OPTARG}") - fi - ;; - e) - EXTRA_TEST_OPTIONS=${OPTARG} - ;; - x) - PHP_XDEBUG_ON=1 - ;; - y) - PHP_XDEBUG_PORT=${OPTARG} - ;; - h) - echo "${HELP}" - exit 0 - ;; - n) - CGLCHECK_DRY_RUN="-n" - ;; - u) - TEST_SUITE=update - ;; - v) - SCRIPT_VERBOSE=1 - ;; - \?) - INVALID_OPTIONS+=(${OPTARG}) - ;; - :) - INVALID_OPTIONS+=(${OPTARG}) - ;; - esac -done - -# Exit on invalid options -if [ ${#INVALID_OPTIONS[@]} -ne 0 ]; then - echo "Invalid option(s):" >&2 - for I in "${INVALID_OPTIONS[@]}"; do - echo "-"${I} >&2 - done - echo >&2 - echo "${HELP}" >&2 - exit 1 -fi - -# Move "7.4" to "php74", the latter is the docker container name -DOCKER_PHP_IMAGE=`echo "php${PHP_VERSION}" | sed -e 's/\.//'` - -# Set $1 to first mass argument, this is the optional test file or test directory to execute -shift $((OPTIND - 1)) -TEST_FILE=${1} - -if [ ${SCRIPT_VERBOSE} -eq 1 ]; then - set -x -fi - -# Suite execution -case ${TEST_SUITE} in - acceptance) - handleDbmsAndDriverOptions - setUpDockerComposeDotEnv - case ${DBMS} in - sqlite) - echo "Using driver: ${DATABASE_DRIVER}" - docker-compose run acceptance_cli_sqlite - SUITE_EXIT_CODE=$? - ;; - mysql) - echo "Using driver: ${DATABASE_DRIVER}" - docker-compose run acceptance_cli_mysql80 - SUITE_EXIT_CODE=$? - ;; - mariadb) - echo "Using driver: ${DATABASE_DRIVER}" - docker-compose run acceptance_cli_mariadb10 - SUITE_EXIT_CODE=$? - ;; - postgres) - docker-compose run acceptance_cli_postgres10 - SUITE_EXIT_CODE=$? - ;; - *) - echo "Acceptance tests don't run with DBMS ${DBMS}" >&2 - echo >&2 - echo "call \"./Build/Scripts/runTests.sh -h\" to display help and valid options" >&2 - exit 1 - esac - docker-compose down - ;; - cgl) - # Active dry-run for cgl needs not "-n" but specific options - if [[ ! -z ${CGLCHECK_DRY_RUN} ]]; then - CGLCHECK_DRY_RUN="--dry-run --diff" - fi - setUpDockerComposeDotEnv - docker-compose run cgl - SUITE_EXIT_CODE=$? - docker-compose down - ;; - clean) - rm -rf ../../composer.lock ../../.Build/ ../../Tests/Acceptance/Support/_generated/ ../../composer.json.testing - ;; - composerUpdate) - setUpDockerComposeDotEnv - cp ../../composer.json ../../composer.json.orig - if [ -f "../../composer.json.testing" ]; then - cp ../../composer.json ../../composer.json.orig - fi - docker-compose run composer_update - cp ../../composer.json ../../composer.json.testing - mv ../../composer.json.orig ../../composer.json - SUITE_EXIT_CODE=$? - docker-compose down - ;; - functional) - handleDbmsAndDriverOptions - setUpDockerComposeDotEnv - case ${DBMS} in - mariadb) - echo "Using driver: ${DATABASE_DRIVER}" - docker-compose run functional_mariadb10 - SUITE_EXIT_CODE=$? - ;; - mysql) - echo "Using driver: ${DATABASE_DRIVER}" - docker-compose run functional_mysql80 - SUITE_EXIT_CODE=$? - ;; - postgres) - docker-compose run functional_postgres10 - SUITE_EXIT_CODE=$? - ;; - sqlite) - # sqlite has a tmpfs as Web/typo3temp/var/tests/functional-sqlite-dbs/ - # Since docker is executed as root (yay!), the path to this dir is owned by - # root if docker creates it. Thank you, docker. We create the path beforehand - # to avoid permission issues. - mkdir -p ${ROOT_DIR}/Web/typo3temp/var/tests/functional-sqlite-dbs/ - docker-compose run functional_sqlite - SUITE_EXIT_CODE=$? - ;; - *) - echo "Invalid -d option argument ${DBMS}" >&2 - echo >&2 - echo "${HELP}" >&2 - exit 1 - esac - docker-compose down - ;; - lint) - setUpDockerComposeDotEnv - docker-compose run lint - SUITE_EXIT_CODE=$? - docker-compose down - ;; - phpstan) - setUpDockerComposeDotEnv - docker-compose run phpstan - SUITE_EXIT_CODE=$? - docker-compose down - ;; - phpstanGenerateBaseline) - setUpDockerComposeDotEnv - docker-compose run phpstan_generate_baseline - SUITE_EXIT_CODE=$? - docker-compose down - ;; - unit) - setUpDockerComposeDotEnv - docker-compose run unit - SUITE_EXIT_CODE=$? - docker-compose down - ;; - update) - # pull typo3/core-testing-*:latest versions of those ones that exist locally - docker images typo3/core-testing-*:latest --format "{{.Repository}}:latest" | xargs -I {} docker pull {} - # remove "dangling" typo3/core-testing-* images (those tagged as ) - docker images typo3/core-testing-* --filter "dangling=true" --format "{{.ID}}" | xargs -I {} docker rmi {} - ;; - *) - echo "Invalid -s option argument ${TEST_SUITE}" >&2 - echo >&2 - echo "${HELP}" >&2 - exit 1 -esac - -exit $SUITE_EXIT_CODE diff --git a/Build/UnitTests.xml b/Build/UnitTests.xml deleted file mode 100644 index a90da4c..0000000 --- a/Build/UnitTests.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - ../Tests/Unit/ - - - - - - - diff --git a/Build/UnitTestsBootstrap.php b/Build/UnitTestsBootstrap.php deleted file mode 100644 index bd41c10..0000000 --- a/Build/UnitTestsBootstrap.php +++ /dev/null @@ -1,75 +0,0 @@ -getWebRoot(), '/')); - } - if (!getenv('TYPO3_PATH_WEB')) { - putenv('TYPO3_PATH_WEB=' . rtrim($testbase->getWebRoot(), '/')); - } - - $testbase->defineSitePath(); - - // We can use the "typo3/cms-composer-installers" constant "TYPO3_COMPOSER_MODE" to determine composer mode. - // This should be always true except for TYPO3 mono repository. - $composerMode = defined('TYPO3_COMPOSER_MODE') && TYPO3_COMPOSER_MODE === true; - $requestType = \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::REQUESTTYPE_BE | \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::REQUESTTYPE_CLI; - SystemEnvironmentBuilder::run(0, $requestType, $composerMode); - - $testbase->createDirectory(Environment::getPublicPath() . '/typo3conf/ext'); - $testbase->createDirectory(Environment::getPublicPath() . '/typo3temp/assets'); - $testbase->createDirectory(Environment::getPublicPath() . '/typo3temp/var/tests'); - $testbase->createDirectory(Environment::getPublicPath() . '/typo3temp/var/transient'); - - // Retrieve an instance of class loader and inject to core bootstrap - $classLoader = require $testbase->getPackagesPath() . '/autoload.php'; - Bootstrap::initializeClassLoader($classLoader); - - // Initialize default TYPO3_CONF_VARS - $configurationManager = new ConfigurationManager(); - $GLOBALS['TYPO3_CONF_VARS'] = $configurationManager->getDefaultConfiguration(); - - $cache = new PhpFrontend( - 'core', - new NullBackend('production', []) - ); - $packageManager = Bootstrap::createPackageManager( - UnitTestPackageManager::class, - Bootstrap::createPackageCache($cache) - ); - - GeneralUtility::setSingletonInstance(PackageManager::class, $packageManager); - ExtensionManagementUtility::setPackageManager($packageManager); - - $testbase->dumpClassLoadingInformation(); - - GeneralUtility::purgeInstances(); -})(); diff --git a/Build/php-cs-fixer/config.php b/Build/php-cs-fixer/config.php deleted file mode 100644 index 11f4f0a..0000000 --- a/Build/php-cs-fixer/config.php +++ /dev/null @@ -1,94 +0,0 @@ -setFinder( - (new PhpCsFixer\Finder()) - ->ignoreVCSIgnored(true) - ->in([ - __DIR__ . '/../../Build/', - __DIR__ . '/../../Classes/', - __DIR__ . '/../../Configuration/', - __DIR__ . '/../../Tests/', - ]) - ) - ->setUsingCache(false) - ->setRiskyAllowed(true) - ->setRules([ - '@DoctrineAnnotation' => true, - '@PSR2' => true, - 'header_comment' => [ - 'header' => $headerComment, - ], - 'array_syntax' => ['syntax' => 'short'], - 'blank_line_after_opening_tag' => true, - 'cast_spaces' => ['space' => 'none'], - 'compact_nullable_typehint' => true, - 'concat_space' => ['spacing' => 'one'], - 'declare_equal_normalize' => ['space' => 'none'], - 'declare_parentheses' => true, - 'dir_constant' => true, - 'function_to_constant' => ['functions' => ['get_called_class', 'get_class', 'get_class_this', 'php_sapi_name', 'phpversion', 'pi']], - 'function_typehint_space' => true, - 'lowercase_cast' => true, - 'method_argument_space' => ['on_multiline' => 'ensure_fully_multiline'], - 'modernize_strpos' => false, - 'modernize_types_casting' => true, - 'native_function_casing' => true, - 'new_with_braces' => true, - 'no_alias_functions' => true, - 'no_blank_lines_after_phpdoc' => true, - 'no_empty_phpdoc' => true, - 'no_empty_statement' => true, - 'no_extra_blank_lines' => true, - 'no_leading_import_slash' => true, - 'no_leading_namespace_whitespace' => true, - 'no_null_property_initialization' => true, - 'no_short_bool_cast' => true, - 'no_singleline_whitespace_before_semicolons' => true, - 'no_superfluous_elseif' => true, - 'no_trailing_comma_in_singleline' => true, - 'no_unneeded_control_parentheses' => true, - 'no_unused_imports' => true, - 'no_useless_else' => true, - 'no_useless_nullsafe_operator' => true, - 'no_whitespace_in_blank_line' => true, - 'ordered_imports' => true, - 'php_unit_construct' => ['assertions' => ['assertEquals', 'assertSame', 'assertNotEquals', 'assertNotSame']], - 'php_unit_mock_short_will_return' => true, - 'php_unit_test_case_static_method_calls' => ['call_type' => 'self'], - 'phpdoc_no_access' => true, - 'phpdoc_no_empty_return' => true, - 'phpdoc_no_package' => true, - 'phpdoc_scalar' => true, - 'phpdoc_trim' => true, - 'phpdoc_types' => true, - 'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'], - 'return_type_declaration' => ['space_before' => 'none'], - 'single_quote' => true, - 'single_space_after_construct' => true, - 'single_line_comment_style' => ['comment_types' => ['hash']], - 'single_trait_insert_per_statement' => true, - 'trailing_comma_in_multiline' => ['elements' => ['arrays']], - 'whitespace_after_comma_in_array' => ['ensure_single_space' => true], - 'yoda_style' => ['equal' => false, 'identical' => false, 'less_and_greater' => false], - ]); diff --git a/Build/testing-docker/docker-compose.yml b/Build/testing-docker/docker-compose.yml deleted file mode 100644 index 692b5ac..0000000 --- a/Build/testing-docker/docker-compose.yml +++ /dev/null @@ -1,398 +0,0 @@ -version: '2.3' -services: - mariadb10: - # not using mariadb:10 for the time being, because 10.5.7 (currently latest) is broken - image: mariadb:10.5.6 - environment: - MYSQL_ROOT_PASSWORD: funcp - tmpfs: - - /var/lib/mysql/:rw,noexec,nosuid - - mysql80: - image: mysql:8.0 - environment: - MYSQL_ROOT_PASSWORD: funcp - tmpfs: - - /var/lib/mysql/:rw,noexec,nosuid - - postgres10: - image: postgres:10-alpine - environment: - POSTGRES_PASSWORD: funcp - POSTGRES_USER: ${HOST_USER} - tmpfs: - - /var/lib/postgresql/data:rw,noexec,nosuid - - acceptance_cli_mariadb10: - image: typo3/core-testing-${DOCKER_PHP_IMAGE}:latest - user: "${HOST_UID}" - links: - - mariadb10 - environment: - typo3DatabaseDriver: "${DATABASE_DRIVER}" - typo3DatabaseName: func_test - typo3DatabaseUsername: root - typo3DatabasePassword: funcp - typo3DatabaseHost: mariadb10 - volumes: - - ${ROOT_DIR}:${ROOT_DIR} - working_dir: ${ROOT_DIR}/ - extra_hosts: - - "host.docker.internal:host-gateway" - command: > - /bin/sh -c " - if [ ${SCRIPT_VERBOSE} -eq 1 ]; then - set -x - fi - echo Waiting for database start...; - while ! nc -z mariadb10 3306; do - sleep 1; - done; - echo Database is up; - php -v | grep '^PHP'; - mkdir -p .Build/Web/typo3temp/var/tests/ - COMMAND=\".Build/vendor/codeception/codeception/codecept run Cli -d -c Tests/codeception.yml ${TEST_FILE}\" - if [ ${PHP_XDEBUG_ON} -eq 0 ]; then - XDEBUG_MODE=\"off\" $${COMMAND}; - else - XDEBUG_MODE=\"debug,develop\" XDEBUG_TRIGGER=\"foo\" XDEBUG_CONFIG=\"client_host=host.docker.internal\" $${COMMAND}; - fi - " - - acceptance_cli_mysql80: - image: typo3/core-testing-${DOCKER_PHP_IMAGE}:latest - user: "${HOST_UID}" - links: - - mysql80 - environment: - typo3DatabaseDriver: "${DATABASE_DRIVER}" - typo3DatabaseName: func_test - typo3DatabaseUsername: root - typo3DatabasePassword: funcp - typo3DatabaseHost: mysql80 - volumes: - - ${ROOT_DIR}:${ROOT_DIR} - working_dir: ${ROOT_DIR} - extra_hosts: - - "host.docker.internal:host-gateway" - command: > - /bin/sh -c " - if [ ${SCRIPT_VERBOSE} -eq 1 ]; then - set -x - fi - echo Waiting for database start...; - while ! nc -z mysql80 3306; do - sleep 1; - done; - echo Database is up; - php -v | grep '^PHP'; - mkdir -p .Build/Web/typo3temp/var/tests/ - COMMAND=\".Build/vendor/codeception/codeception/codecept run Cli -d -c Tests/codeception.yml ${TEST_FILE}\" - if [ ${PHP_XDEBUG_ON} -eq 0 ]; then - XDEBUG_MODE=\"off\" $${COMMAND}; - else - XDEBUG_MODE=\"debug,develop\" XDEBUG_TRIGGER=\"foo\" XDEBUG_CONFIG=\"client_host=host.docker.internal\" $${COMMAND}; - fi - " - - acceptance_cli_postgres10: - image: typo3/core-testing-${DOCKER_PHP_IMAGE}:latest - user: "${HOST_UID}" - links: - - postgres10 - environment: - typo3DatabaseDriver: pdo_pgsql - typo3DatabaseName: bamboo - typo3DatabaseUsername: ${HOST_USER} - typo3DatabaseHost: postgres10 - typo3DatabasePassword: funcp - volumes: - - ${ROOT_DIR}:${ROOT_DIR} - working_dir: ${ROOT_DIR} - extra_hosts: - - "host.docker.internal:host-gateway" - command: > - /bin/sh -c " - if [ ${SCRIPT_VERBOSE} -eq 1 ]; then - set -x - fi - echo Waiting for database start...; - while ! nc -z postgres10 5432; do - sleep 1; - done; - echo Database is up; - php -v | grep '^PHP'; - mkdir -p .Build/Web/typo3temp/var/tests/ - COMMAND=\".Build/vendor/codeception/codeception/codecept run Cli -d -c Tests/codeception.yml ${TEST_FILE}\" - if [ ${PHP_XDEBUG_ON} -eq 0 ]; then - XDEBUG_MODE=\"off\" $${COMMAND}; - else - XDEBUG_MODE=\"debug,develop\" XDEBUG_TRIGGER=\"foo\" XDEBUG_CONFIG=\"client_host=host.docker.internal\" $${COMMAND}; - fi - " - - acceptance_cli_sqlite: - image: typo3/core-testing-${DOCKER_PHP_IMAGE}:latest - user: "${HOST_UID}" - environment: - typo3DatabaseDriver: pdo_sqlite - volumes: - - ${ROOT_DIR}:${ROOT_DIR} - working_dir: ${ROOT_DIR} - extra_hosts: - - "host.docker.internal:host-gateway" - command: > - /bin/sh -c " - if [ ${SCRIPT_VERBOSE} -eq 1 ]; then - set -x - fi - php -v | grep '^PHP'; - mkdir -p Web/typo3temp/var/tests/ - COMMAND=\".Build/vendor/codeception/codeception/codecept run Cli -d -c Tests/codeception.yml ${TEST_FILE}\" - if [ ${PHP_XDEBUG_ON} -eq 0 ]; then - XDEBUG_MODE=\"off\" $${COMMAND}; - else - XDEBUG_MODE=\"debug,develop\" XDEBUG_TRIGGER=\"foo\" XDEBUG_CONFIG=\"client_host=host.docker.internal\" $${COMMAND}; - fi - " - - cgl: - image: typo3/core-testing-${DOCKER_PHP_IMAGE}:latest - user: "${HOST_UID}" - volumes: - - ${ROOT_DIR}:${ROOT_DIR} - working_dir: ${ROOT_DIR} - extra_hosts: - - "host.docker.internal:host-gateway" - command: > - /bin/sh -c " - if [ ${SCRIPT_VERBOSE} -eq 1 ]; then - set -x - fi - php -v | grep '^PHP'; - if [ ${PHP_XDEBUG_ON} -eq 0 ]; then - php -dxdebug.mode=off .Build/bin/php-cs-fixer fix -v ${CGLCHECK_DRY_RUN} --config=Build/php-cs-fixer/config.php - else - XDEBUG_MODE=\"debug,develop\" XDEBUG_TRIGGER=\"foo\" XDEBUG_CONFIG=\"client_host=host.docker.internal\" PHP_CS_FIXER_ALLOW_XDEBUG=1 .Build/bin/php-cs-fixer fix -v ${CGLCHECK_DRY_RUN} --config=Build/php-cs-fixer/config.php - fi - " - - composer_update: - image: typo3/core-testing-${DOCKER_PHP_IMAGE}:latest - user: "${HOST_UID}" - volumes: - - ${ROOT_DIR}:${ROOT_DIR} - working_dir: ${ROOT_DIR} - environment: - COMPOSER_CACHE_DIR: ".cache/composer" - command: > - /bin/sh -c " - if [ ${SCRIPT_VERBOSE} -eq 1 ]; then - set -x - fi - php -v | grep '^PHP'; - if [ ${TYPO3_VERSION} -eq 11 ]; then - composer req --dev --no-update typo3/cms-composer-installers:^3.0 typo3/cms-workspaces:^11.5 typo3/cms-impexp:^11.5 - composer req typo3/cms-core:^11.5 --no-update - fi - if [ ${TYPO3_VERSION} -eq 12 ]; then - composer req --dev --no-update "typo3/cms-composer-installers:^5.0" typo3/cms-impexp:^12.4 typo3/cms-workspaces:^12.4 - composer req typo3/cms-core:^12.4 --no-update - fi - composer update --no-progress --no-interaction; - " - - functional_mariadb10: - image: typo3/core-testing-${DOCKER_PHP_IMAGE}:latest - user: "${HOST_UID}" - links: - - mariadb10 - volumes: - - ${ROOT_DIR}:${ROOT_DIR} - environment: - typo3DatabaseDriver: "${DATABASE_DRIVER}" - typo3DatabaseName: func_test - typo3DatabaseUsername: root - typo3DatabasePassword: funcp - typo3DatabaseHost: mariadb10 - working_dir: ${ROOT_DIR} - extra_hosts: - - "host.docker.internal:host-gateway" - command: > - /bin/sh -c " - if [ ${SCRIPT_VERBOSE} -eq 1 ]; then - set -x - fi - echo Waiting for database start...; - while ! nc -z mariadb10 3306; do - sleep 1; - done; - echo Database is up; - php -v | grep '^PHP'; - if [ ${PHP_XDEBUG_ON} -eq 0 ]; then - php -dxdebug.mode=off .Build/bin/phpunit -c Build/FunctionalTests.xml ${EXTRA_TEST_OPTIONS} ${TEST_FILE}; - else - php -dxdebug.mode='debug,develop' XDEBUG_TRIGGER='foo' XDEBUG_CONFIG='client_host=host.docker.internal' .Build/bin/phpunit -c Build/FunctionalTests.xml ${EXTRA_TEST_OPTIONS} ${TEST_FILE}; - fi - " - - functional_mysql80: - image: typo3/core-testing-${DOCKER_PHP_IMAGE}:latest - user: "${HOST_UID}" - links: - - mysql80 - volumes: - - ${ROOT_DIR}:${ROOT_DIR} - environment: - typo3DatabaseDriver: "${DATABASE_DRIVER}" - typo3DatabaseName: func_test - typo3DatabaseUsername: root - typo3DatabasePassword: funcp - typo3DatabaseHost: mysql80 - working_dir: ${ROOT_DIR} - extra_hosts: - - "host.docker.internal:host-gateway" - command: > - /bin/sh -c " - if [ ${SCRIPT_VERBOSE} -eq 1 ]; then - set -x - fi - echo Waiting for database start...; - while ! nc -z mysql80 3306; do - sleep 1; - done; - echo Database is up; - php -v | grep '^PHP'; - if [ ${PHP_XDEBUG_ON} -eq 0 ]; then - XDEBUG_MODE=\"off\" .Build/bin/phpunit -c Build/FunctionalTests.xml ${EXTRA_TEST_OPTIONS} ${TEST_FILE}; - else - XDEBUG_MODE=\"debug,develop\" XDEBUG_TRIGGER=\"foo\" XDEBUG_CONFIG=\"client_host=host.docker.internal\" .Build/bin/phpunit -c Build/FunctionalTests.xml ${EXTRA_TEST_OPTIONS} ${TEST_FILE}; - fi - " - - functional_postgres10: - image: typo3/core-testing-${DOCKER_PHP_IMAGE}:latest - user: "${HOST_UID}" - links: - - postgres10 - volumes: - - ${ROOT_DIR}:${ROOT_DIR} - environment: - typo3DatabaseDriver: pdo_pgsql - typo3DatabaseName: bamboo - typo3DatabaseUsername: ${HOST_USER} - typo3DatabaseHost: postgres10 - typo3DatabasePassword: funcp - working_dir: ${ROOT_DIR} - extra_hosts: - - "host.docker.internal:host-gateway" - command: > - /bin/sh -c " - if [ ${SCRIPT_VERBOSE} -eq 1 ]; then - set -x - fi - echo Waiting for database start...; - while ! nc -z postgres10 5432; do - sleep 1; - done; - echo Database is up; - php -v | grep '^PHP'; - if [ ${PHP_XDEBUG_ON} -eq 0 ]; then - XDEBUG_MODE=\"off\" .Build/bin/phpunit -c Build/FunctionalTests.xml ${EXTRA_TEST_OPTIONS} --exclude-group not-postgres ${TEST_FILE}; - else - XDEBUG_MODE=\"debug,develop\" XDEBUG_TRIGGER=\"foo\" XDEBUG_CONFIG=\"client_host=host.docker.internal\" .Build/bin/phpunit -c Build/FunctionalTests.xml ${EXTRA_TEST_OPTIONS} --exclude-group not-postgres ${TEST_FILE}; - fi - " - - functional_sqlite: - image: typo3/core-testing-${DOCKER_PHP_IMAGE}:latest - user: "${HOST_UID}" - volumes: - - ${ROOT_DIR}:${ROOT_DIR} - tmpfs: - - ${ROOT_DIR}/Web/typo3temp/var/tests/functional-sqlite-dbs/:rw,noexec,nosuid,uid=${HOST_UID} - environment: - typo3DatabaseDriver: pdo_sqlite - working_dir: ${ROOT_DIR} - extra_hosts: - - "host.docker.internal:host-gateway" - command: > - /bin/sh -c " - if [ ${SCRIPT_VERBOSE} -eq 1 ]; then - set -x - fi - php -v | grep '^PHP'; - if [ ${PHP_XDEBUG_ON} -eq 0 ]; then - XDEBUG_MODE=\"off\" .Build/bin/phpunit -c Build/FunctionalTests.xml ${EXTRA_TEST_OPTIONS} --exclude-group not-sqlite ${TEST_FILE}; - else - XDEBUG_MODE=\"debug,develop\" XDEBUG_TRIGGER=\"foo\" XDEBUG_CONFIG=\"client_host=host.docker.internal\" .Build/bin/phpunit -c Build/FunctionalTests.xml ${EXTRA_TEST_OPTIONS} --exclude-group not-sqlite ${TEST_FILE}; - fi - " - - lint: - image: typo3/core-testing-${DOCKER_PHP_IMAGE}:latest - user: "${HOST_UID}" - volumes: - - ${ROOT_DIR}:${ROOT_DIR} - working_dir: ${ROOT_DIR} - command: > - /bin/sh -c " - if [ ${SCRIPT_VERBOSE} -eq 1 ]; then - set -x - fi - php -v | grep '^PHP'; - find . -name \\*.php ! -path "./.Build/\\*" -print0 | xargs -0 -n1 -P4 php -dxdebug.mode=off -l >/dev/null - " - - phpstan: - image: typo3/core-testing-${DOCKER_PHP_IMAGE}:latest - user: "${HOST_UID}" - volumes: - - ${ROOT_DIR}:${ROOT_DIR} - working_dir: ${ROOT_DIR} - command: > - /bin/sh -c " - if [ ${SCRIPT_VERBOSE} -eq 1 ]; then - set -x - fi - mkdir -p .Build/.cache - php -v | grep '^PHP'; - php -dxdebug.mode=off .Build/bin/phpstan analyze -c Build/phpstan.neon --no-progress - " - - phpstan_generate_baseline: - image: typo3/core-testing-${DOCKER_PHP_IMAGE}:latest - user: "${HOST_UID}" - volumes: - - ${ROOT_DIR}:${ROOT_DIR} - working_dir: ${ROOT_DIR} - command: > - /bin/sh -c " - if [ ${SCRIPT_VERBOSE} -eq 1 ]; then - set -x - fi - mkdir -p .Build/.cache - php -v | grep '^PHP'; - php -dxdebug.mode=off .Build/bin/phpstan analyze -c Build/phpstan.neon --generate-baseline=Build/phpstan-baseline.neon - " - - unit: - image: typo3/core-testing-${DOCKER_PHP_IMAGE}:latest - user: "${HOST_UID}" - volumes: - - ${ROOT_DIR}:${ROOT_DIR} - working_dir: ${ROOT_DIR} - extra_hosts: - - "host.docker.internal:host-gateway" - command: > - /bin/sh -c " - if [ ${SCRIPT_VERBOSE} -eq 1 ]; then - set -x - fi - php -v | grep '^PHP'; - if [ ${PHP_XDEBUG_ON} -eq 0 ]; then - XDEBUG_MODE=\"off\" .Build/bin/phpunit -c Build/UnitTests.xml ${EXTRA_TEST_OPTIONS} ${TEST_FILE}; - else - XDEBUG_MODE=\"debug,develop\" XDEBUG_TRIGGER=\"foo\" XDEBUG_CONFIG=\"client_host=host.docker.internal\" .Build/bin/phpunit -c Build/UnitTests.xml ${EXTRA_TEST_OPTIONS} ${TEST_FILE}; - fi - " \ No newline at end of file diff --git a/Tests/Functional/Configuration/ReplaceConfigurationTest.php b/Tests/Functional/Configuration/ReplaceConfigurationTest.php index 7156e63..59d1e9c 100644 --- a/Tests/Functional/Configuration/ReplaceConfigurationTest.php +++ b/Tests/Functional/Configuration/ReplaceConfigurationTest.php @@ -36,7 +36,7 @@ public function getSearchValueInitiallyReturnsEmptyString(): void { self::assertSame( '', - $this->subject->getSearchValue() + $this->subject->getSearchValue(), ); } @@ -49,7 +49,7 @@ public function setSearchValueWillSetSearchValue(): void self::assertSame( 'foo bar', - $this->subject->getSearchValue() + $this->subject->getSearchValue(), ); } @@ -60,7 +60,7 @@ public function getReplaceValueInitiallyReturnsEmptyString() { self::assertSame( '', - $this->subject->getReplaceValue() + $this->subject->getReplaceValue(), ); } @@ -73,7 +73,7 @@ public function setReplaceValueSetsReplaceValue() self::assertSame( 'foo bar', - $this->subject->getReplaceValue() + $this->subject->getReplaceValue(), ); } @@ -83,7 +83,7 @@ public function setReplaceValueSetsReplaceValue() public function getUseRegExpInitiallyReturnsFalse() { self::assertFalse( - $this->subject->isUseRegExp() + $this->subject->isUseRegExp(), ); } @@ -95,7 +95,7 @@ public function setUseRegExpSetsUseRegExp() $this->subject->setUseRegExp(true); self::assertTrue( - $this->subject->isUseRegExp() + $this->subject->isUseRegExp(), ); } } diff --git a/Tests/Functional/Enumeration/ConfigurationTypeEnumerationTest.php b/Tests/Functional/Enumeration/ConfigurationTypeEnumerationTest.php index 8bb401d..b1c36fe 100644 --- a/Tests/Functional/Enumeration/ConfigurationTypeEnumerationTest.php +++ b/Tests/Functional/Enumeration/ConfigurationTypeEnumerationTest.php @@ -37,7 +37,7 @@ public function configurationTypeAsStringWillReturnDefaultValue(): void { self::assertSame( 'search.', - (string)$this->subject + (string)$this->subject, ); } @@ -50,7 +50,7 @@ public function setValueToSearchWillAppendDot(): void self::assertSame( 'search.', - (string)$subject + (string)$subject, ); } @@ -63,7 +63,7 @@ public function setValueToReplaceWillAppendDot(): void self::assertSame( 'replace.', - (string)$subject + (string)$subject, ); } diff --git a/Tests/Functional/FrontendRequest/ReplaceContentCachedTest.php b/Tests/Functional/FrontendRequest/ReplaceContentCachedTest.php index f98fa4f..db5be11 100644 --- a/Tests/Functional/FrontendRequest/ReplaceContentCachedTest.php +++ b/Tests/Functional/FrontendRequest/ReplaceContentCachedTest.php @@ -33,7 +33,7 @@ protected function setUp(): void 1, [ 'EXT:replacer/Tests/Functional/Fixtures/basic_template.typoscript', - ] + ], ); } @@ -43,7 +43,7 @@ protected function setUp(): void public function frontendRequestDoNotReplacesContentOnTypo3Error(): void { $response = self::executeFrontendSubRequest( - new InternalRequest('https://website.local/site-not-found') + new InternalRequest('https://website.local/site-not-found'), ); $body = (string)$response->getBody(); @@ -52,11 +52,11 @@ public function frontendRequestDoNotReplacesContentOnTypo3Error(): void // which will result in an uninitialized TSFE or methods on null exception self::assertStringNotContainsString( 'TSFE', - $body + $body, ); self::assertStringNotContainsString( 'null', - $body + $body, ); } @@ -66,14 +66,14 @@ public function frontendRequestDoNotReplacesContentOnTypo3Error(): void public function frontendRequestReplacesContent(): void { $response = self::executeFrontendSubRequest( - new InternalRequest('https://website.local/') + new InternalRequest('https://website.local/'), ); $body = (string)$response->getBody(); self::assertStringContainsString( 'I like fruits', - $body + $body, ); } } diff --git a/Tests/Functional/FrontendRequest/ReplaceContentUnCachedTest.php b/Tests/Functional/FrontendRequest/ReplaceContentUnCachedTest.php index 59453d4..f0d4821 100644 --- a/Tests/Functional/FrontendRequest/ReplaceContentUnCachedTest.php +++ b/Tests/Functional/FrontendRequest/ReplaceContentUnCachedTest.php @@ -34,7 +34,7 @@ protected function setUp(): void [ 'EXT:replacer/Tests/Functional/Fixtures/basic_template.typoscript', 'EXT:replacer/Tests/Functional/Fixtures/user_int.typoscript', - ] + ], ); } @@ -44,7 +44,7 @@ protected function setUp(): void public function frontendRequestDoNotReplacesContentOnTypo3Error(): void { $response = self::executeFrontendSubRequest( - new InternalRequest('https://website.local/site-not-found') + new InternalRequest('https://website.local/site-not-found'), ); $body = (string)$response->getBody(); @@ -53,11 +53,11 @@ public function frontendRequestDoNotReplacesContentOnTypo3Error(): void // which will result in an uninitialized TSFE or methods on null exception self::assertStringNotContainsString( 'TSFE', - $body + $body, ); self::assertStringNotContainsString( 'null', - $body + $body, ); } @@ -67,14 +67,14 @@ public function frontendRequestDoNotReplacesContentOnTypo3Error(): void public function frontendRequestReplacesContent(): void { $response = self::executeFrontendSubRequest( - new InternalRequest('https://website.local/') + new InternalRequest('https://website.local/'), ); $body = (string)$response->getBody(); self::assertStringContainsString( 'I like fruits', - $body + $body, ); } } diff --git a/Tests/Functional/Helper/ReplacerHelperTest.php b/Tests/Functional/Helper/ReplacerHelperTest.php index 07d640a..0ebedfe 100644 --- a/Tests/Functional/Helper/ReplacerHelperTest.php +++ b/Tests/Functional/Helper/ReplacerHelperTest.php @@ -126,7 +126,7 @@ public function replaceContentWithValidSearchAndReplaceValues( self::assertSame( $result, - $actualResult + $actualResult, ); } diff --git a/Tests/Functional/Helper/TypoScriptHelperTest.php b/Tests/Functional/Helper/TypoScriptHelperTest.php index 0bc4970..d698121 100644 --- a/Tests/Functional/Helper/TypoScriptHelperTest.php +++ b/Tests/Functional/Helper/TypoScriptHelperTest.php @@ -53,7 +53,7 @@ public function hasStdWrapPropertiesWillReturnFalse(array $config, $key, bool $e { self::assertSame( $expected, - $this->subject->hasStdWrapProperties($config, $key) + $this->subject->hasStdWrapProperties($config, $key), ); } @@ -78,7 +78,7 @@ public function getStdWrapPropertiesWillReturnFalse(array $config, $key, array $ { self::assertSame( $expected, - $this->subject->getStdWrapProperties($config, $key) + $this->subject->getStdWrapProperties($config, $key), ); } @@ -93,8 +93,8 @@ public function findValueOrConfigurationWillReturnEmptyString(): void [ 20 => 'TEXT', ], - 10 - ) + 10, + ), ); } @@ -112,8 +112,8 @@ public function findValueOrConfigurationWillReturnBaseNode(): void 'value' => 'foo bar', ], ], - 10 - ) + 10, + ), ); } @@ -133,7 +133,7 @@ public function findValueOrConfigurationWillReturnProperties(): void ], ], '10.', - ) + ), ); } @@ -148,7 +148,7 @@ public function isRegExpEnabledOnBaseNodeWillReturnFalse(): void 10 => 'TEXT', ], '10.', - ) + ), ); } @@ -165,8 +165,8 @@ public function isRegExpEnabledWithDisabledRegExWillReturnFalse(): void 'enable_regex' => '0', ], ], - '10.' - ) + '10.', + ), ); } @@ -183,8 +183,8 @@ public function isRegExpEnabledWithoutRegExPropertyWillReturnFalse(): void 'wrap' => '|', ], ], - '10.' - ) + '10.', + ), ); } @@ -201,8 +201,8 @@ public function isRegExpEnabledWithActivatedRegExWillReturnTrue(): void 'enable_regex' => '1', ], ], - '10.' - ) + '10.', + ), ); } @@ -219,8 +219,8 @@ public function hasBaseEntryWillReturnTrue(): void 'enable_regex' => '1', ], ], - '10.' - ) + '10.', + ), ); } @@ -236,8 +236,8 @@ public function hasBaseEntryWillReturnFalse(): void 'wrap' => '|', ], ], - '10.' - ) + '10.', + ), ); } @@ -254,8 +254,8 @@ public function hasReplaceEntryWithBaseNodeWillReturnTrue(): void 'wrap' => '|', ], ], - '10.' - ) + '10.', + ), ); } @@ -271,8 +271,8 @@ public function hasReplaceEntryWithoutBaseNodeWillReturnTrue(): void 'wrap' => '|', ], ], - '10.' - ) + '10.', + ), ); } @@ -289,8 +289,8 @@ public function hasReplaceEntryWillReturnFalse(): void 'wrap' => '|', ], ], - 20 - ) + 20, + ), ); } @@ -317,8 +317,8 @@ public function applyStdWrapProperties(): void 'apple', [ 'wrap' => '|', - ] - ) + ], + ), ); } } diff --git a/Tests/Functional/Hooks/TypoScriptFrontendControllerHookTest.php b/Tests/Functional/Hooks/TypoScriptFrontendControllerHookTest.php index 8bd8f7a..ff6dcd8 100644 --- a/Tests/Functional/Hooks/TypoScriptFrontendControllerHookTest.php +++ b/Tests/Functional/Hooks/TypoScriptFrontendControllerHookTest.php @@ -33,7 +33,7 @@ protected function setUp(): void [ 'EXT:replacer/Tests/Functional/Fixtures/basic_template.typoscript', 'EXT:replacer/Tests/Functional/Fixtures/user_int.typoscript', - ] + ], ); } @@ -44,7 +44,7 @@ public function frontendRequestUsesReplacerForBasicReplacementOnPageWithoutUserI { self::assertEquals( '

I like fruits

This is MD5 Hash Example: 0800fc577294c34e0b28ad2839435945

Hello world

', - $this->getFrontendResponse(1)->getContent() + $this->getFrontendResponse(1)->getContent(), ); } } diff --git a/Tests/Functional/Middleware/ReplaceContentMiddlewareTest.php b/Tests/Functional/Middleware/ReplaceContentMiddlewareTest.php index 5b21e1d..599d994 100644 --- a/Tests/Functional/Middleware/ReplaceContentMiddlewareTest.php +++ b/Tests/Functional/Middleware/ReplaceContentMiddlewareTest.php @@ -32,7 +32,7 @@ protected function setUp(): void [ 'EXT:replacer/Tests/Functional/Fixtures/basic_template.typoscript', 'EXT:replacer/Tests/Functional/Fixtures/user_int.typoscript', - ] + ], ); } @@ -43,7 +43,7 @@ public function frontendRequestReplacesContentAsDescribedInTypoScriptOnPageWithU { self::assertEquals( '

I like fruits

This is MD5 Hash Example: 0800fc577294c34e0b28ad2839435945

Hello world

', - $this->getFrontendResponse(1)->getContent() + $this->getFrontendResponse(1)->getContent(), ); } } From bc61da645b710e3f8aded6aa24a6434264d8c21f Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Mon, 21 Oct 2024 10:43:51 +0200 Subject: [PATCH 03/13] [TASK] New TestSuite GitHub Action workflow CI --- .github/workflows/ci.yml | 65 ++- Build/Scripts/runTests.sh | 608 +++++++++++++++++++++ Build/cgl/.php-cs-fixer.dist.php | 102 ++++ Build/phpstan/phpstan-baseline.neon | 7 + Build/phpstan/phpstan-typo3-constants.php | 12 + Build/phpstan/phpstan.neon | 19 + Build/phpunit/FunctionalTests.xml | 26 + Build/phpunit/FunctionalTestsBootstrap.php | 17 + Build/phpunit/UnitTests.xml | 26 + Build/phpunit/UnitTestsBootstrap.php | 97 ++++ 10 files changed, 945 insertions(+), 34 deletions(-) create mode 100755 Build/Scripts/runTests.sh create mode 100644 Build/cgl/.php-cs-fixer.dist.php create mode 100644 Build/phpstan/phpstan-baseline.neon create mode 100644 Build/phpstan/phpstan-typo3-constants.php create mode 100644 Build/phpstan/phpstan.neon create mode 100644 Build/phpunit/FunctionalTests.xml create mode 100644 Build/phpunit/FunctionalTestsBootstrap.php create mode 100644 Build/phpunit/UnitTests.xml create mode 100644 Build/phpunit/UnitTestsBootstrap.php diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ecae596..6efd393 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,53 +1,50 @@ -name: Test replacer for TYPO3 12 LTS +name: Tests -on: - pull_request: +on: [pull_request] jobs: - CGL: - name: Coding Style Check (TYPO3 Community CGL) + testing: + name: Testing runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Composer - run: Build/Scripts/runTests.sh -t 12 -p 8.1 -s composerUpdate + strategy: + fail-fast: true - - name: Lint PHP - run: Build/Scripts/runTests.sh -t 12 -p 8.1 -s lint + matrix: + php: + - '7.4' + - '8.0' + - '8.1' + - '8.2' - - name: Validate code against CGL - run: Build/Scripts/runTests.sh -t 12 -p 8.1 -s cgl -n + steps: + - name: 'Checkout' + uses: actions/checkout@v4 - testsuite: - name: PHP Unit and Functional Tests for TYPO3 Version 12 LTS + - name: 'Lint PHP' + run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s lint - needs: CGL + - name: 'Install testing system' + run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s composerUpdate - runs-on: ubuntu-latest + - name: 'Composer validate' + run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s composerValidate - strategy: - matrix: - php: [ '8.1', '8.2' ] + - name: 'Composer normalize' + run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s composerNormalize -n - steps: - - name: Checkout - uses: actions/checkout@v3 + - name: 'CGL' + run: Build/Scripts/runTests.sh -n -p ${{ matrix.php }} -s cgl - - name: Composer - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -t 12 -s composerUpdate + - name: 'Execute unit tests' + run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s unit - - name: Lint PHP - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s lint + - name: 'Execute functional tests' + run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -d mysql -s functional - - name: Functional tests with mariadb + - name: 'Execute functional tests' run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -d mariadb -s functional - - name: Functional tests with postgres + - name: 'Execute functional tests' run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -d postgres -s functional - - - name: Functional tests with sqlite - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -d sqlite -s functional diff --git a/Build/Scripts/runTests.sh b/Build/Scripts/runTests.sh new file mode 100755 index 0000000..21e2373 --- /dev/null +++ b/Build/Scripts/runTests.sh @@ -0,0 +1,608 @@ +#!/usr/bin/env bash + +# +# EXT:examples test runner based on docker/podman. +# + +trap 'cleanUp;exit 2' SIGINT + +waitFor() { + local HOST=${1} + local PORT=${2} + local TESTCOMMAND=" + COUNT=0; + while ! nc -z ${HOST} ${PORT}; do + if [ \"\${COUNT}\" -gt 10 ]; then + echo \"Can not connect to ${HOST} port ${PORT}. Aborting.\"; + exit 1; + fi; + sleep 1; + COUNT=\$((COUNT + 1)); + done; + " + ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name wait-for-${SUFFIX} ${XDEBUG_MODE} -e XDEBUG_CONFIG="${XDEBUG_CONFIG}" ${IMAGE_ALPINE} /bin/sh -c "${TESTCOMMAND}" + if [[ $? -gt 0 ]]; then + kill -SIGINT -$$ + fi +} + +cleanUp() { + ATTACHED_CONTAINERS=$(${CONTAINER_BIN} ps --filter network=${NETWORK} --format='{{.Names}}') + for ATTACHED_CONTAINER in ${ATTACHED_CONTAINERS}; do + ${CONTAINER_BIN} rm -f ${ATTACHED_CONTAINER} >/dev/null + done + ${CONTAINER_BIN} network rm ${NETWORK} >/dev/null +} + +cleanCacheFiles() { + echo -n "Clean caches ... " + rm -rf \ + .Build/.cache \ + .php-cs-fixer.cache + echo "done" +} + +cleanRenderedDocumentationFiles() { + echo -n "Clean rendered documentation files ... " + rm -rf \ + Documentation-GENERATED-temp + echo "done" +} + +handleDbmsOptions() { + # -a, -d, -i depend on each other. Validate input combinations and set defaults. + case ${DBMS} in + mariadb) + [ -z "${DATABASE_DRIVER}" ] && DATABASE_DRIVER="mysqli" + if [ "${DATABASE_DRIVER}" != "mysqli" ] && [ "${DATABASE_DRIVER}" != "pdo_mysql" ]; then + echo "Invalid combination -d ${DBMS} -a ${DATABASE_DRIVER}" >&2 + echo >&2 + echo "Use \".Build/Scripts/runTests.sh -h\" to display help and valid options" >&2 + exit 1 + fi + [ -z "${DBMS_VERSION}" ] && DBMS_VERSION="10.4" + if ! [[ ${DBMS_VERSION} =~ ^(10.4|10.5|10.6|10.7|10.8|10.9|10.10|10.11|11.0|11.1)$ ]]; then + echo "Invalid combination -d ${DBMS} -i ${DBMS_VERSION}" >&2 + echo >&2 + echo "Use \".Build/Scripts/runTests.sh -h\" to display help and valid options" >&2 + exit 1 + fi + ;; + mysql) + [ -z "${DATABASE_DRIVER}" ] && DATABASE_DRIVER="mysqli" + if [ "${DATABASE_DRIVER}" != "mysqli" ] && [ "${DATABASE_DRIVER}" != "pdo_mysql" ]; then + echo "Invalid combination -d ${DBMS} -a ${DATABASE_DRIVER}" >&2 + echo >&2 + echo "Use \".Build/Scripts/runTests.sh -h\" to display help and valid options" >&2 + exit 1 + fi + [ -z "${DBMS_VERSION}" ] && DBMS_VERSION="8.0" + if ! [[ ${DBMS_VERSION} =~ ^(8.0|8.1|8.2|8.3)$ ]]; then + echo "Invalid combination -d ${DBMS} -i ${DBMS_VERSION}" >&2 + echo >&2 + echo "Use \".Build/Scripts/runTests.sh -h\" to display help and valid options" >&2 + exit 1 + fi + ;; + postgres) + if [ -n "${DATABASE_DRIVER}" ]; then + echo "Invalid combination -d ${DBMS} -a ${DATABASE_DRIVER}" >&2 + echo >&2 + echo "Use \".Build/Scripts/runTests.sh -h\" to display help and valid options" >&2 + exit 1 + fi + [ -z "${DBMS_VERSION}" ] && DBMS_VERSION="10" + if ! [[ ${DBMS_VERSION} =~ ^(10|11|12|13|14|15|16)$ ]]; then + echo "Invalid combination -d ${DBMS} -i ${DBMS_VERSION}" >&2 + echo >&2 + echo "Use \".Build/Scripts/runTests.sh -h\" to display help and valid options" >&2 + exit 1 + fi + ;; + sqlite) + if [ -n "${DATABASE_DRIVER}" ]; then + echo "Invalid combination -d ${DBMS} -a ${DATABASE_DRIVER}" >&2 + echo >&2 + echo "Use \".Build/Scripts/runTests.sh -h\" to display help and valid options" >&2 + exit 1 + fi + if [ -n "${DBMS_VERSION}" ]; then + echo "Invalid combination -d ${DBMS} -i ${DATABASE_DRIVER}" >&2 + echo >&2 + echo "Use \".Build/Scripts/runTests.sh -h\" to display help and valid options" >&2 + exit 1 + fi + ;; + *) + echo "Invalid option -d ${DBMS}" >&2 + echo >&2 + echo "Use \".Build/Scripts/runTests.sh -h\" to display help and valid options" >&2 + exit 1 + ;; + esac +} + +loadHelp() { + # Load help text into $HELP + read -r -d '' HELP < + Specifies which test suite to run + - cgl: cgl test and fix all php files + - clean: Clean temporary files + - cleanCache: Clean cache folds for files. + - cleanRenderedDocumentation: Clean existing rendered documentation output. + - composer: "composer" with all remaining arguments dispatched. + - composerNormalize: "composer normalize" + - composerUpdate: "composer update", handy if host has no PHP + - composerUpdateRector: "composer update", for rector subdirectory + - composerValidate: "composer validate" + - functional: PHP functional tests + - lint: PHP linting + - phpstan: PHPStan static analysis + - phpstanBaseline: Generate PHPStan baseline + - unit: PHP unit tests + - rector: Apply Rector rules + - renderDocumentation + - testRenderDocumentation + + -b + Container environment: + - docker + - podman + + If not specified, podman will be used if available. Otherwise, docker is used. + + -a + Only with -s functional|functionalDeprecated + Specifies to use another driver, following combinations are available: + - mysql + - mysqli (default) + - pdo_mysql + - mariadb + - mysqli (default) + - pdo_mysql + + -d + Only with -s functional|functionalDeprecated|acceptance|acceptanceComposer|acceptanceInstall + Specifies on which DBMS tests are performed + - sqlite: (default): use sqlite + - mariadb: use mariadb + - mysql: use MySQL + - postgres: use postgres + + -i version + Specify a specific database version + With "-d mariadb": + - 10.4 short-term, maintained until 2024-06-18 (default) + - 10.5 short-term, maintained until 2025-06-24 + - 10.6 long-term, maintained until 2026-06 + - 10.7 short-term, no longer maintained + - 10.8 short-term, maintained until 2023-05 + - 10.9 short-term, maintained until 2023-08 + - 10.10 short-term, maintained until 2023-11 + - 10.11 long-term, maintained until 2028-02 + - 11.0 development series + - 11.1 short-term development series + With "-d mysql": + - 8.0 maintained until 2026-04 (default) LTS + - 8.1 unmaintained since 2023-10 + - 8.2 unmaintained since 2024-01 + - 8.3 maintained until 2024-04 + With "-d postgres": + - 10 unmaintained since 2022-11-10 (default) + - 11 unmaintained since 2023-11-09 + - 12 maintained until 2024-11-14 + - 13 maintained until 2025-11-13 + - 14 maintained until 2026-11-12 + - 15 maintained until 2027-11-11 + - 16 maintained until 2028-11-09 + + -p <7.4|8.0|8.1|8.2|8.3> + Specifies the PHP minor version to be used + - 7.4: use PHP 7.4 + - 8.0: use PHP 8.0 + - 8.1: use PHP 8.1 + - 8.2: use PHP 8.2 + - 8.3: use PHP 8.3 + + -x + Only with -s functional|unit + Send information to host instance for test or system under test break points. This is especially + useful if a local PhpStorm instance is listening on default xdebug port 9003. A different port + can be selected with -y + + -y + Send xdebug information to a different port than default 9003 if an IDE like PhpStorm + is not listening on default port. + + -n + Only with -s cgl, composerNormalize, rector + Activate dry-run in CGL check and composer normalize that does not actively change files and only prints broken ones. + + -u + Update existing typo3/core-testing-*:latest container images and remove dangling local volumes. + New images are published once in a while and only the latest ones are supported by core testing. + Use this if weird test errors occur. Also removes obsolete image versions of typo3/core-testing-*. + + -h + Show this help. + +Examples: + # Run unit tests using PHP 8.2 + ./Build/Scripts/runTests.sh -p 8.2 -s unit + + # Run functional tests using PHP 8.3 and MariaDB 10.6 using pdo_mysql + ./Build/Scripts/runTests.sh -p 8.3 -s functional -d mariadb -i 10.6 -a pdo_mysql + + # Run functional tests on postgres with xdebug, php 8.3 and execute a restricted set of tests + ./Build/Scripts/runTests.sh -x -p 8.3 -s functional -d postgres -- Tests/Functional/DummyTest.php +EOF +} + +# Test if docker exists, else exit out with error +if ! type "docker" >/dev/null 2>&1 && ! type "podman" >/dev/null 2>&1; then + echo "This script relies on docker or podman. Please install" >&2 + exit 1 +fi + +# Option defaults +# @todo Consider to switch from cgl to help as default +TEST_SUITE="cgl" +DATABASE_DRIVER="" +DBMS="sqlite" +DBMS_VERSION="" +PHP_VERSION="7.4" +PHP_XDEBUG_ON=0 +PHP_XDEBUG_PORT=9003 +CGLCHECK_DRY_RUN=0 +CI_PARAMS="${CI_PARAMS:-}" +DOCS_PARAMS="${DOCS_PARAMS:=--pull always}" +CONTAINER_BIN="" +CONTAINER_HOST="host.docker.internal" + +# Option parsing updates above default vars +# Reset in case getopts has been used previously in the shell +OPTIND=1 +# Array for invalid options +INVALID_OPTIONS=() +# Simple option parsing based on getopts (! not getopt) +while getopts "a:b:d:i:s:p:xy:nhu" OPT; do + case ${OPT} in + a) + DATABASE_DRIVER=${OPTARG} + ;; + s) + TEST_SUITE=${OPTARG} + ;; + b) + if ! [[ ${OPTARG} =~ ^(docker|podman)$ ]]; then + INVALID_OPTIONS+=("${OPTARG}") + fi + CONTAINER_BIN=${OPTARG} + ;; + d) + DBMS=${OPTARG} + ;; + i) + DBMS_VERSION=${OPTARG} + ;; + p) + PHP_VERSION=${OPTARG} + if ! [[ ${PHP_VERSION} =~ ^(7.4|8.0|8.1|8.2|8.3)$ ]]; then + INVALID_OPTIONS+=("p ${OPTARG}") + fi + ;; + x) + PHP_XDEBUG_ON=1 + ;; + y) + PHP_XDEBUG_PORT=${OPTARG} + ;; + n) + CGLCHECK_DRY_RUN=1 + ;; + h) + loadHelp + echo "${HELP}" + exit 0 + ;; + u) + TEST_SUITE=update + ;; + \?) + INVALID_OPTIONS+=("${OPTARG}") + ;; + :) + INVALID_OPTIONS+=("${OPTARG}") + ;; + esac +done + +# Exit on invalid options +if [ ${#INVALID_OPTIONS[@]} -ne 0 ]; then + echo "Invalid option(s):" >&2 + for I in "${INVALID_OPTIONS[@]}"; do + echo "-"${I} >&2 + done + echo >&2 + echo "call \".Build/Scripts/runTests.sh -h\" to display help and valid options" + exit 1 +fi + +handleDbmsOptions + +COMPOSER_ROOT_VERSION="13.0.x-dev" +HOST_UID=$(id -u) +USERSET="" +if [ $(uname) != "Darwin" ]; then + USERSET="--user $HOST_UID" +fi + +# Go to the directory this script is located, so everything else is relative +# to this dir, no matter from where this script is called, then go up two dirs. +THIS_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" +cd "$THIS_SCRIPT_DIR" || exit 1 +cd ../../ || exit 1 +ROOT_DIR="${PWD}" + +# Create .cache dir: composer need this. +mkdir -p .Build/.cache +mkdir -p .Build/web/typo3temp/var/tests + +IMAGE_PREFIX="docker.io/" +# Non-CI fetches TYPO3 images (php and nodejs) from ghcr.io +TYPO3_IMAGE_PREFIX="ghcr.io/typo3/" +CONTAINER_INTERACTIVE="-it --init" + +IS_CORE_CI=0 +# ENV var "CI" is set by gitlab-ci. We use it here to distinct 'local' and 'CI' environment. +if [ "${CI}" == "true" ]; then + IS_CORE_CI=1 + IMAGE_PREFIX="" + CONTAINER_INTERACTIVE="" +fi + +# determine default container binary to use: 1. podman 2. docker +if [[ -z "${CONTAINER_BIN}" ]]; then + if type "podman" >/dev/null 2>&1; then + CONTAINER_BIN="podman" + elif type "docker" >/dev/null 2>&1; then + CONTAINER_BIN="docker" + fi +fi + +IMAGE_PHP="${TYPO3_IMAGE_PREFIX}core-testing-$(echo "php${PHP_VERSION}" | sed -e 's/\.//'):latest" +IMAGE_ALPINE="${IMAGE_PREFIX}alpine:3.8" +IMAGE_MARIADB="docker.io/mariadb:${DBMS_VERSION}" +IMAGE_MYSQL="docker.io/mysql:${DBMS_VERSION}" +IMAGE_POSTGRES="docker.io/postgres:${DBMS_VERSION}-alpine" +IMAGE_DOCS="ghcr.io/typo3-documentation/render-guides:latest" + +# Set $1 to first mass argument, this is the optional test file or test directory to execute +shift $((OPTIND - 1)) + +SUFFIX=$(echo $RANDOM) +NETWORK="t3docsexamples-${SUFFIX}" +${CONTAINER_BIN} network create ${NETWORK} >/dev/null + +if [ ${CONTAINER_BIN} = "docker" ]; then + # docker needs the add-host for xdebug remote debugging. podman has host.container.internal built in + CONTAINER_COMMON_PARAMS="${CONTAINER_INTERACTIVE} --rm --network ${NETWORK} --add-host "${CONTAINER_HOST}:host-gateway" ${USERSET} -v ${ROOT_DIR}:${ROOT_DIR} -w ${ROOT_DIR}" + CONTAINER_DOCS_PARAMS="${CONTAINER_INTERACTIVE} ${DOCS_PARAMS} --rm --network ${NETWORK} --add-host "${CONTAINER_HOST}:host-gateway" ${USERSET} -v ${ROOT_DIR}:/project" +else + # podman + CONTAINER_HOST="host.containers.internal" + CONTAINER_COMMON_PARAMS="${CONTAINER_INTERACTIVE} ${CI_PARAMS} --rm --network ${NETWORK} -v ${ROOT_DIR}:${ROOT_DIR} -w ${ROOT_DIR}" + CONTAINER_DOCS_PARAMS="${CONTAINER_INTERACTIVE} ${DOCS_PARAMS} --rm --network ${NETWORK} -v ${ROOT_DIR}:/project" +fi + +if [ ${PHP_XDEBUG_ON} -eq 0 ]; then + XDEBUG_MODE="-e XDEBUG_MODE=off" + XDEBUG_CONFIG=" " +else + XDEBUG_MODE="-e XDEBUG_MODE=debug -e XDEBUG_TRIGGER=foo" + XDEBUG_CONFIG="client_port=${PHP_XDEBUG_PORT} client_host=${CONTAINER_HOST}" +fi + +# Suite execution +case ${TEST_SUITE} in + cgl) + if [ "${CGLCHECK_DRY_RUN}" -eq 1 ]; then + COMMAND="php -dxdebug.mode=off .Build/bin/php-cs-fixer fix -v --dry-run --diff --config=Build/cgl/.php-cs-fixer.dist.php --using-cache=no ." + else + COMMAND="php -dxdebug.mode=off .Build/bin/php-cs-fixer fix -v --config=Build/cgl/.php-cs-fixer.dist.php --using-cache=no ." + fi + ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name cgl-${SUFFIX} -e COMPOSER_CACHE_DIR=.Build/.cache/composer -e COMPOSER_ROOT_VERSION=${COMPOSER_ROOT_VERSION} ${IMAGE_PHP} /bin/sh -c "${COMMAND}" + SUITE_EXIT_CODE=$? + ;; + clean) + cleanCacheFiles + cleanRenderedDocumentationFiles + ;; + cleanCache) + cleanCacheFiles + ;; + cleanRenderedDocumentation) + cleanRenderedDocumentationFiles + ;; + composer) + COMMAND=(composer "$@") + ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name composer-command-${SUFFIX} -e COMPOSER_CACHE_DIR=.Build/.cache/composer -e COMPOSER_ROOT_VERSION=${COMPOSER_ROOT_VERSION} ${IMAGE_PHP} "${COMMAND[@]}" + SUITE_EXIT_CODE=$? + ;; + composerNormalize) + if [ "${CGLCHECK_DRY_RUN}" -eq 1 ]; then + COMMAND=(composer normalize -n) + else + COMMAND=(composer normalize) + fi + ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name composer-command-${SUFFIX} -e COMPOSER_CACHE_DIR=.Build/.cache/composer -e COMPOSER_ROOT_VERSION=${COMPOSER_ROOT_VERSION} ${IMAGE_PHP} "${COMMAND[@]}" + SUITE_EXIT_CODE=$? + ;; + composerUpdate) + rm -rf .Build/bin/ .Build/typo3 .Build/vendor .Build/Web ./composer.lock + cp ${ROOT_DIR}/composer.json ${ROOT_DIR}/composer.json.orig + if [ -f "${ROOT_DIR}/composer.json.testing" ]; then + cp ${ROOT_DIR}/composer.json ${ROOT_DIR}/composer.json.orig + fi + COMMAND=(composer require --no-ansi --no-interaction --no-progress) + ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name composer-install-${SUFFIX} -e COMPOSER_CACHE_DIR=.Build/.cache/composer -e COMPOSER_ROOT_VERSION=${COMPOSER_ROOT_VERSION} ${IMAGE_PHP} "${COMMAND[@]}" + SUITE_EXIT_CODE=$? + cp ${ROOT_DIR}/composer.json ${ROOT_DIR}/composer.json.testing + mv ${ROOT_DIR}/composer.json.orig ${ROOT_DIR}/composer.json + ;; + composerUpdateRector) + rm -rf Build/rector/.Build/bin/ Build/rector/.Build/vendor Build/rector/composer.lock + cp ${ROOT_DIR}/Build/rector/composer.json ${ROOT_DIR}/Build/rector/composer.json.orig + if [ -f "${ROOT_DIR}/Build/rector/composer.json.testing" ]; then + cp ${ROOT_DIR}/Build/rector/composer.json ${ROOT_DIR}/Build/rector/composer.json.orig + fi + COMMAND=(composer require --working-dir=${ROOT_DIR}/Build/rector --no-ansi --no-interaction --no-progress) + ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name composer-install-${SUFFIX} -e COMPOSER_CACHE_DIR=.Build/.cache/composer -e COMPOSER_ROOT_VERSION=${COMPOSER_ROOT_VERSION} ${IMAGE_PHP} "${COMMAND[@]}" + SUITE_EXIT_CODE=$? + cp ${ROOT_DIR}/Build/rector/composer.json ${ROOT_DIR}/Build/rector/composer.json.testing + mv ${ROOT_DIR}/Build/rector/composer.json.orig ${ROOT_DIR}/Build/rector/composer.json + ;; + composerValidate) + COMMAND=(composer validate "$@") + ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name composer-command-${SUFFIX} -e COMPOSER_CACHE_DIR=.Build/.cache/composer -e COMPOSER_ROOT_VERSION=${COMPOSER_ROOT_VERSION} ${IMAGE_PHP} "${COMMAND[@]}" + SUITE_EXIT_CODE=$? + ;; + functional) + CONTAINER_PARAMS="" + COMMAND=(.Build/bin/phpunit -c Build/phpunit/FunctionalTests.xml --exclude-group not-${DBMS} ${EXTRA_TEST_OPTIONS} "$@") + case ${DBMS} in + mariadb) + echo "Using driver: ${DATABASE_DRIVER}" + ${CONTAINER_BIN} run --rm ${CI_PARAMS} --name mariadb-func-${SUFFIX} --network ${NETWORK} -d -e MYSQL_ROOT_PASSWORD=funcp --tmpfs /var/lib/mysql/:rw,noexec,nosuid ${IMAGE_MARIADB} >/dev/null + waitFor mariadb-func-${SUFFIX} 3306 + CONTAINERPARAMS="-e typo3DatabaseDriver=${DATABASE_DRIVER} -e typo3DatabaseName=func_test -e typo3DatabaseUsername=root -e typo3DatabaseHost=mariadb-func-${SUFFIX} -e typo3DatabasePassword=funcp" + ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name functional-${SUFFIX} ${XDEBUG_MODE} -e XDEBUG_CONFIG="${XDEBUG_CONFIG}" ${CONTAINERPARAMS} ${IMAGE_PHP} "${COMMAND[@]}" + SUITE_EXIT_CODE=$? + ;; + mysql) + echo "Using driver: ${DATABASE_DRIVER}" + ${CONTAINER_BIN} run --rm ${CI_PARAMS} --name mysql-func-${SUFFIX} --network ${NETWORK} -d -e MYSQL_ROOT_PASSWORD=funcp --tmpfs /var/lib/mysql/:rw,noexec,nosuid ${IMAGE_MYSQL} >/dev/null + waitFor mysql-func-${SUFFIX} 3306 + CONTAINERPARAMS="-e typo3DatabaseDriver=${DATABASE_DRIVER} -e typo3DatabaseName=func_test -e typo3DatabaseUsername=root -e typo3DatabaseHost=mysql-func-${SUFFIX} -e typo3DatabasePassword=funcp" + ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name functional-${SUFFIX} ${XDEBUG_MODE} -e XDEBUG_CONFIG="${XDEBUG_CONFIG}" ${CONTAINERPARAMS} ${IMAGE_PHP} "${COMMAND[@]}" + SUITE_EXIT_CODE=$? + ;; + postgres) + ${CONTAINER_BIN} run --rm ${CI_PARAMS} --name postgres-func-${SUFFIX} --network ${NETWORK} -d -e POSTGRES_PASSWORD=funcp -e POSTGRES_USER=funcu --tmpfs /var/lib/postgresql/data:rw,noexec,nosuid ${IMAGE_POSTGRES} >/dev/null + waitFor postgres-func-${SUFFIX} 5432 + CONTAINERPARAMS="-e typo3DatabaseDriver=pdo_pgsql -e typo3DatabaseName=bamboo -e typo3DatabaseUsername=funcu -e typo3DatabaseHost=postgres-func-${SUFFIX} -e typo3DatabasePassword=funcp" + ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name functional-${SUFFIX} ${XDEBUG_MODE} -e XDEBUG_CONFIG="${XDEBUG_CONFIG}" ${CONTAINERPARAMS} ${IMAGE_PHP} "${COMMAND[@]}" + SUITE_EXIT_CODE=$? + ;; + sqlite) + # create sqlite tmpfs mount typo3temp/var/tests/functional-sqlite-dbs/ to avoid permission issues + mkdir -p "${ROOT_DIR}/.Build/web/typo3temp/var/tests/functional-sqlite-dbs/" + CONTAINERPARAMS="-e typo3DatabaseDriver=pdo_sqlite --tmpfs ${ROOT_DIR}/.Build/web/typo3temp/var/tests/functional-sqlite-dbs/:rw,noexec,nosuid" + ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name functional-${SUFFIX} ${XDEBUG_MODE} -e XDEBUG_CONFIG="${XDEBUG_CONFIG}" ${CONTAINERPARAMS} ${IMAGE_PHP} "${COMMAND[@]}" + SUITE_EXIT_CODE=$? + ;; + esac + ;; + lint) + COMMAND="find . -name \\*.php ! -path "./.Build/\\*" -print0 | xargs -0 -n1 -P4 php -dxdebug.mode=off -l >/dev/null" + ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name composer-command-${SUFFIX} -e COMPOSER_CACHE_DIR=.Build/.cache/composer -e COMPOSER_ROOT_VERSION=${COMPOSER_ROOT_VERSION} ${IMAGE_PHP} /bin/sh -c "${COMMAND}" + SUITE_EXIT_CODE=$? + ;; + phpstan) + COMMAND="php -dxdebug.mode=off .Build/bin/phpstan --configuration=Build/phpstan/phpstan.neon" + ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name phpstan-${SUFFIX} -e COMPOSER_CACHE_DIR=.Build/.cache/composer -e COMPOSER_ROOT_VERSION=${COMPOSER_ROOT_VERSION} ${IMAGE_PHP} /bin/sh -c "${COMMAND}" + SUITE_EXIT_CODE=$? + ;; + phpstanBaseline) + COMMAND="php -dxdebug.mode=off .Build/bin/phpstan --configuration=Build/phpstan/phpstan.neon --generate-baseline=Build/phpstan/phpstan-baseline.neon -v" + ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name phpstan-${SUFFIX} -e COMPOSER_CACHE_DIR=.Build/.cache/composer -e COMPOSER_ROOT_VERSION=${COMPOSER_ROOT_VERSION} ${IMAGE_PHP} /bin/sh -c "${COMMAND}" + SUITE_EXIT_CODE=$? + ;; + rector) + if [ "${CGLCHECK_DRY_RUN}" -eq 1 ]; then + COMMAND=(php -dxdebug.mode=off Build/rector/.Build/bin/rector -n --config=Build/rector/rector.php --clear-cache "$@") + else + COMMAND=(php -dxdebug.mode=off Build/rector/.Build/bin/rector --config=Build/rector/rector.php --clear-cache "$@") + fi + ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name rector-${SUFFIX} -e COMPOSER_CACHE_DIR=.Build/.cache/composer -e COMPOSER_ROOT_VERSION=${COMPOSER_ROOT_VERSION} ${IMAGE_PHP} "${COMMAND[@]}" + SUITE_EXIT_CODE=$? + ;; + renderDocumentation) + COMMAND=(--config=Documentation "$@") + mkdir -p Documentation-GENERATED-temp + ${CONTAINER_BIN} run ${CONTAINER_INTERACTIVE} ${CONTAINER_DOCS_PARAMS} --name render-documentation-${SUFFIX} ${IMAGE_DOCS} "${COMMAND[@]}" + SUITE_EXIT_CODE=$? + ;; + testRenderDocumentation) + COMMAND=(--config=Documentation --no-progress --fail-on-log "$@") + mkdir -p Documentation-GENERATED-temp + ${CONTAINER_BIN} run ${CONTAINER_INTERACTIVE} ${CONTAINER_DOCS_PARAMS} --name render-documentation-test-${SUFFIX} ${IMAGE_DOCS} "${COMMAND[@]}" + SUITE_EXIT_CODE=$? + ;; + unit) + COMMAND=(.Build/bin/phpunit -c Build/phpunit/UnitTests.xml ${EXTRA_TEST_OPTIONS} "$@") + ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name unit-${SUFFIX} ${XDEBUG_MODE} -e XDEBUG_CONFIG="${XDEBUG_CONFIG}" ${IMAGE_PHP} "${COMMAND[@]}" + SUITE_EXIT_CODE=$? + ;; + update) + # pull typo3/core-testing-* versions of those ones that exist locally + echo "> pull ${TYPO3_IMAGE_PREFIX}core-testing-* versions of those ones that exist locally" + ${CONTAINER_BIN} images "${TYPO3_IMAGE_PREFIX}core-testing-*" --format "{{.Repository}}:{{.Tag}}" | xargs -I {} ${CONTAINER_BIN} pull {} + echo "" + # remove "dangling" typo3/core-testing-* images (those tagged as ) + echo "> remove \"dangling\" ${TYPO3_IMAGE_PREFIX}/core-testing-* images (those tagged as )" + ${CONTAINER_BIN} images --filter "reference=${TYPO3_IMAGE_PREFIX}/core-testing-*" --filter "dangling=true" --format "{{.ID}}" | xargs -I {} ${CONTAINER_BIN} rmi -f {} + echo "" + ;; + *) + loadHelp + echo "Invalid -s option argument ${TEST_SUITE}" >&2 + echo >&2 + echo "${HELP}" >&2 + exit 1 + ;; +esac + +cleanUp + +# Print summary +echo "" >&2 +echo "###########################################################################" >&2 +echo "Result of ${TEST_SUITE}" >&2 +echo "Container runtime: ${CONTAINER_BIN}" >&2 +if [[ ${IS_CORE_CI} -eq 1 ]]; then + echo "Environment: CI" >&2 +else + echo "Environment: local" >&2 +fi +echo "PHP: ${PHP_VERSION}" >&2 +echo "TYPO3: ${CORE_VERSION}" >&2 +if [[ ${TEST_SUITE} =~ ^functional$ ]]; then + case "${DBMS}" in + mariadb|mysql) + echo "DBMS: ${DBMS} version ${DBMS_VERSION} driver ${DATABASE_DRIVER}" >&2 + ;; + postgres) + echo "DBMS: ${DBMS} version ${DBMS_VERSION} driver pdo_pgsql" >&2 + ;; + sqlite) + echo "DBMS: ${DBMS} driver pdo_sqlite" >&2 + ;; + esac +fi +if [[ ${SUITE_EXIT_CODE} -eq 0 ]]; then + echo "SUCCESS" >&2 +else + echo "FAILURE" >&2 +fi +echo "###########################################################################" >&2 +echo "" >&2 + +# Exit with code of test suite - This script return non-zero if the executed test failed. +exit $SUITE_EXIT_CODE diff --git a/Build/cgl/.php-cs-fixer.dist.php b/Build/cgl/.php-cs-fixer.dist.php new file mode 100644 index 0000000..ee7802f --- /dev/null +++ b/Build/cgl/.php-cs-fixer.dist.php @@ -0,0 +1,102 @@ +setFinder( + (new Finder()) + ->in(__DIR__ . '/../../') + ->exclude(__DIR__ . '/../../.Build') + ->exclude(__DIR__ . '/../../var') + ) + ->setRiskyAllowed(true) + ->setRules([ + '@DoctrineAnnotation' => true, + 'header_comment' => [ + 'header' => $headerComment, + ], + // @todo: Switch to @PER-CS2.0 once php-cs-fixer's todo list is done: https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/7247 + '@PER-CS1.0' => true, + 'array_indentation' => true, + 'array_syntax' => ['syntax' => 'short'], + 'cast_spaces' => ['space' => 'none'], + // @todo: Can be dropped once we enable @PER-CS2.0 + 'concat_space' => ['spacing' => 'one'], + 'declare_equal_normalize' => ['space' => 'none'], + 'declare_parentheses' => true, + 'dir_constant' => true, + // @todo: Can be dropped once we enable @PER-CS2.0 + 'function_declaration' => [ + 'closure_fn_spacing' => 'none', + ], + 'function_to_constant' => ['functions' => ['get_called_class', 'get_class', 'get_class_this', 'php_sapi_name', 'phpversion', 'pi']], + 'type_declaration_spaces' => true, + 'global_namespace_import' => ['import_classes' => false, 'import_constants' => false, 'import_functions' => false], + 'list_syntax' => ['syntax' => 'short'], + // @todo: Can be dropped once we enable @PER-CS2.0 + 'method_argument_space' => true, + 'modernize_strpos' => true, + 'modernize_types_casting' => true, + 'native_function_casing' => true, + 'no_alias_functions' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_empty_phpdoc' => true, + 'no_empty_statement' => true, + 'no_extra_blank_lines' => true, + 'no_leading_namespace_whitespace' => true, + 'no_null_property_initialization' => true, + 'no_short_bool_cast' => true, + 'no_singleline_whitespace_before_semicolons' => true, + 'no_superfluous_elseif' => true, + 'no_trailing_comma_in_singleline' => true, + 'no_unneeded_control_parentheses' => true, + 'no_unused_imports' => true, + 'no_useless_nullsafe_operator' => true, + 'ordered_imports' => ['imports_order' => ['class', 'function', 'const'], 'sort_algorithm' => 'alpha'], + 'php_unit_construct' => ['assertions' => ['assertEquals', 'assertSame', 'assertNotEquals', 'assertNotSame']], + 'php_unit_mock_short_will_return' => true, + 'php_unit_test_case_static_method_calls' => ['call_type' => 'self'], + 'phpdoc_no_access' => true, + 'phpdoc_no_empty_return' => true, + 'phpdoc_no_package' => true, + 'phpdoc_scalar' => true, + 'phpdoc_trim' => true, + 'phpdoc_types' => true, + 'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'], + 'return_type_declaration' => ['space_before' => 'none'], + 'single_quote' => true, + 'single_space_around_construct' => true, + 'single_line_comment_style' => ['comment_types' => ['hash']], + // @todo: Can be dropped once we enable @PER-CS2.0 + 'single_line_empty_body' => true, + 'trailing_comma_in_multiline' => ['elements' => ['arguments', 'arrays', 'match', 'parameters']], + 'whitespace_after_comma_in_array' => ['ensure_single_space' => true], + 'yoda_style' => ['equal' => false, 'identical' => false, 'less_and_greater' => false], + + // We need this for documentation! + 'no_useless_else' => false, // We want to preserve else with comments only + + // Add this rule to convert FQCN to use statements + 'full_opening_tag' => true, + ]); diff --git a/Build/phpstan/phpstan-baseline.neon b/Build/phpstan/phpstan-baseline.neon new file mode 100644 index 0000000..dd8ccf1 --- /dev/null +++ b/Build/phpstan/phpstan-baseline.neon @@ -0,0 +1,7 @@ +parameters: + # Ignore specific errors: + ignoreErrors: + - + message: '#Call to an undefined method .*#' + #- + # message: '#^Access to an undefined property TYPO3\\\\CMS\\\\Scheduler\\\\Task\\\\AbstractTask$#' diff --git a/Build/phpstan/phpstan-typo3-constants.php b/Build/phpstan/phpstan-typo3-constants.php new file mode 100644 index 0000000..0956596 --- /dev/null +++ b/Build/phpstan/phpstan-typo3-constants.php @@ -0,0 +1,12 @@ + + + + + + + ../../Tests/Functional/ + + + + + + + diff --git a/Build/phpunit/FunctionalTestsBootstrap.php b/Build/phpunit/FunctionalTestsBootstrap.php new file mode 100644 index 0000000..f5ff1c9 --- /dev/null +++ b/Build/phpunit/FunctionalTestsBootstrap.php @@ -0,0 +1,17 @@ +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..d1fc4f0 --- /dev/null +++ b/Build/phpunit/UnitTests.xml @@ -0,0 +1,26 @@ + + + + + + + ../../Tests/Unit/ + + + + + + + diff --git a/Build/phpunit/UnitTestsBootstrap.php b/Build/phpunit/UnitTestsBootstrap.php new file mode 100644 index 0000000..b4ed0f2 --- /dev/null +++ b/Build/phpunit/UnitTestsBootstrap.php @@ -0,0 +1,97 @@ +getWebRoot(), '/')); + } + if (!getenv('TYPO3_PATH_WEB')) { + putenv('TYPO3_PATH_WEB=' . rtrim($testbase->getWebRoot(), '/')); + } + + $testbase->defineSitePath(); + + // We can use the "typo3/cms-composer-installers" constant "TYPO3_COMPOSER_MODE" to determine composer mode. + // This should be always true except for TYPO3 mono repository. + $composerMode = defined('TYPO3_COMPOSER_MODE') && TYPO3_COMPOSER_MODE === true; + + // @todo: Remove else branch when dropping support for v12 + $hasConsolidatedHttpEntryPoint = class_exists(CoreHttpApplication::class); + if ($hasConsolidatedHttpEntryPoint) { + SystemEnvironmentBuilder::run(0, \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::REQUESTTYPE_CLI, $composerMode); + } else { + $requestType = \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::REQUESTTYPE_BE | \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::REQUESTTYPE_CLI; + SystemEnvironmentBuilder::run(0, $requestType, $composerMode); + } + + $testbase->createDirectory(Environment::getPublicPath() . '/typo3conf/ext'); + $testbase->createDirectory(Environment::getPublicPath() . '/typo3temp/assets'); + $testbase->createDirectory(Environment::getPublicPath() . '/typo3temp/var/tests'); + $testbase->createDirectory(Environment::getPublicPath() . '/typo3temp/var/transient'); + + // Retrieve an instance of class loader and inject to core bootstrap + $classLoader = require $testbase->getPackagesPath() . '/autoload.php'; + Bootstrap::initializeClassLoader($classLoader); + + // Initialize default TYPO3_CONF_VARS + $configurationManager = new ConfigurationManager(); + $GLOBALS['TYPO3_CONF_VARS'] = $configurationManager->getDefaultConfiguration(); + + $cache = new PhpFrontend( + 'core', + new NullBackend('production', []), + ); + $packageManager = Bootstrap::createPackageManager( + UnitTestPackageManager::class, + Bootstrap::createPackageCache($cache), + ); + + GeneralUtility::setSingletonInstance(PackageManager::class, $packageManager); + ExtensionManagementUtility::setPackageManager($packageManager); + + $testbase->dumpClassLoadingInformation(); + + GeneralUtility::purgeInstances(); +})(); From 0ec08f9c9a6395480aa6eddcf967ecfb880d371f Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Mon, 21 Oct 2024 10:44:09 +0200 Subject: [PATCH 04/13] [TASK] Updated README badges --- README.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/README.md b/README.md index 503cdf7..aa7429f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,15 @@ # TYPO3 Extension `replacer` +[![Packagist][packagist-logo-stable]][extension-packagist-url] +[![Latest Stable Version][extension-build-shield]][extension-ter-url] +[![License][LICENSE_BADGE]][extension-packagist-url] +[![Total Downloads][extension-downloads-badge]][extension-packagist-url] +[![Monthly Downloads][extension-monthly-downloads]][extension-packagist-url] +[![TYPO3 11.5][TYPO3-shield-11]][TYPO3-11-url] +[![TYPO3 12.4][TYPO3-shield]][TYPO3-12-url] + +![Build Status][extension-ci-shield] + ## What does it do? Walks through generated HTML Output of TYPO3 and replaces various links with lins from @@ -20,3 +30,30 @@ composer require jweiland/replacer Login into TYPO3 Backend of your project and click on `Extensions` in the left menu. Press the `Retrieve/Update` button and search for the extension key `replacer`. Import the extension from TER (TYPO3 Extension Repository) + + + + +[extension-build-shield]: https://poser.pugx.org/jweiland/replacer/v/stable.svg?style=for-the-badge + +[extension-ci-shield]: https://github.com/jweiland-net/replacer/actions/workflows/ci.yml/badge.svg + +[extension-downloads-badge]: https://poser.pugx.org/jweiland/replacer/d/total.svg?style=for-the-badge + +[extension-monthly-downloads]: https://poser.pugx.org/jweiland/replacer/d/monthly?style=for-the-badge + +[extension-ter-url]: https://extensions.typo3.org/extension/replacer/ + +[extension-packagist-url]: https://packagist.org/packages/jweiland/replacer/ + +[packagist-logo-stable]: https://img.shields.io/badge/--grey.svg?style=for-the-badge&logo=packagist&logoColor=white + +[TYPO3-11-url]: https://get.typo3.org/version/11 + +[TYPO3-12-url]: https://get.typo3.org/version/12 + +[TYPO3-shield]: https://img.shields.io/badge/TYPO3-12.4-green.svg?style=for-the-badge&logo=typo3 + +[TYPO3-shield-11]: https://img.shields.io/badge/TYPO3-11.5-green.svg?style=for-the-badge&logo=typo3 + +[LICENSE_BADGE]: https://img.shields.io/github/license/jweiland-net/replacer?label=license&style=for-the-badge From 5978f8b954aa8420140f691f0868be05e6ec1ece Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Mon, 21 Oct 2024 10:44:59 +0200 Subject: [PATCH 05/13] [TASK] Installed composer normalizer changes --- composer.json | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/composer.json b/composer.json index 391c24a..ddc00c2 100644 --- a/composer.json +++ b/composer.json @@ -1,10 +1,14 @@ { "name": "jweiland/replacer", - "type": "typo3-cms-extension", "description": "Replaces string patterns from the page. You can use it to replace URLs for Content Delivery Network (CDN).", "license": "GPL-2.0-or-later", - "keywords": ["typo3", "TYPO3 CMS", "jw", "replacer"], - "homepage": "https://jweiland.net", + "type": "typo3-cms-extension", + "keywords": [ + "typo3", + "TYPO3 CMS", + "jw", + "replacer" + ], "authors": [ { "name": "Hoja Mustaffa Abdul Latheef", @@ -17,17 +21,20 @@ "role": "Developer" } ], + "homepage": "https://jweiland.net", "support": { "email": "projects@jweiland.net", "issues": "https://github.com/jweiland-net/replacer/issues", "source": "https://github.com/jweiland-net/replacer" }, "require": { - "typo3/cms-core": "^11.5.30 || ^12.4.4" + "typo3/cms-core": "^11.5.37 || ^12.4.15" }, "require-dev": { + "ergebnis/composer-normalize": "~2.42.0", "friendsofphp/php-cs-fixer": "^3.14", "phpunit/phpunit": "^9.6", + "roave/security-advisories": "dev-latest", "typo3/coding-standards": "^0.6", "typo3/testing-framework": "^7.0.2" }, @@ -50,13 +57,14 @@ } }, "config": { - "sort-packages": true, - "vendor-dir": ".Build/vendor", - "bin-dir": ".Build/bin", "allow-plugins": { - "typo3/cms-composer-installers": true, - "typo3/class-alias-loader": true - } + "ergebnis/composer-normalize": true, + "typo3/class-alias-loader": true, + "typo3/cms-composer-installers": true + }, + "bin-dir": ".Build/bin", + "sort-packages": true, + "vendor-dir": ".Build/vendor" }, "extra": { "typo3/cms": { From 4dccb2269d2401f0cfb50eebde8569ca5762eb90 Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Mon, 21 Oct 2024 10:45:27 +0200 Subject: [PATCH 06/13] [TASK] Update version changes --- ext_emconf.php | 11 +++++++++-- ext_localconf.php | 7 +++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/ext_emconf.php b/ext_emconf.php index 5aabbff..9ed90dd 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -1,5 +1,12 @@ 'Content Replacer', 'description' => 'Replaces string patterns from the page. You can use it to replace URLs for Content Delivery Network (CDN).', @@ -8,10 +15,10 @@ 'author_email' => 'projects@jweiland.net', 'author_company' => 'jweiland.net', 'state' => 'stable', - 'version' => '3.0.3', + 'version' => '3.0.4', 'constraints' => [ 'depends' => [ - 'typo3' => '11.5.30-12.4.99', + 'typo3' => '11.5.37-12.4.99', ], 'conflicts' => [], 'suggests' => [], diff --git a/ext_localconf.php b/ext_localconf.php index a7d8c02..8cbfb57 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -1,5 +1,12 @@ Date: Mon, 21 Oct 2024 10:46:02 +0200 Subject: [PATCH 07/13] [TASK] Fixed few more lint formating issues --- ...CacheableContentGeneratedEventListener.php | 2 +- Classes/Helper/ReplacerHelper.php | 28 +++++++++---------- .../Hook/TypoScriptFrontendControllerHook.php | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Classes/EventListener/CacheableContentGeneratedEventListener.php b/Classes/EventListener/CacheableContentGeneratedEventListener.php index b636190..5abde25 100644 --- a/Classes/EventListener/CacheableContentGeneratedEventListener.php +++ b/Classes/EventListener/CacheableContentGeneratedEventListener.php @@ -42,7 +42,7 @@ public function __invoke(AfterCacheableContentIsGeneratedEvent $event): void } $event->getController()->content = $this->replacerHelper->replace( - $event->getController()->content + $event->getController()->content, ); } } diff --git a/Classes/Helper/ReplacerHelper.php b/Classes/Helper/ReplacerHelper.php index d0e12fa..ff0f00e 100644 --- a/Classes/Helper/ReplacerHelper.php +++ b/Classes/Helper/ReplacerHelper.php @@ -53,7 +53,7 @@ public function replace(string $contentToReplace): string $typoScriptFrontendController = $this->getTypoScriptFrontendController(); $replacerTypoScriptConfiguration = $this->getValueByPath( $typoScriptFrontendController->config, - 'config/tx_replacer.' + 'config/tx_replacer.', ); foreach ($this->getReplaceConfigurationStorage($replacerTypoScriptConfiguration) as $replaceConfiguration) { @@ -62,14 +62,14 @@ public function replace(string $contentToReplace): string $contentToReplace = (string)preg_replace( $replaceConfiguration->getSearchValue(), $replaceConfiguration->getReplaceValue(), - $contentToReplace + $contentToReplace, ); } else { // replace using a regular strings as search pattern $contentToReplace = (string)str_replace( $replaceConfiguration->getSearchValue(), $replaceConfiguration->getReplaceValue(), - $contentToReplace + $contentToReplace, ); } } @@ -86,12 +86,12 @@ protected function getReplaceConfigurationStorage(array $replacerTypoScriptConfi $searchTypoScriptConfiguration = $this->getConfigurationFor( $replacerTypoScriptConfiguration, - ConfigurationTypeEnumeration::cast('search') + ConfigurationTypeEnumeration::cast('search'), ); $replaceTypoScriptConfiguration = $this->getConfigurationFor( $replacerTypoScriptConfiguration, - ConfigurationTypeEnumeration::cast('replace') + ConfigurationTypeEnumeration::cast('replace'), ); foreach ($searchTypoScriptConfiguration as $key => $valueOrConfiguration) { @@ -111,12 +111,12 @@ protected function getReplaceConfigurationStorage(array $replacerTypoScriptConfi // Add regular expression information $replaceConfiguration->setUseRegExp( - $this->typoScriptHelper->isRegExpEnabled($searchTypoScriptConfiguration, $key) + $this->typoScriptHelper->isRegExpEnabled($searchTypoScriptConfiguration, $key), ); // Add search value $replaceConfiguration->setSearchValue( - $this->getProcessedValue($valueOrConfiguration, $searchTypoScriptConfiguration, $key) + $this->getProcessedValue($valueOrConfiguration, $searchTypoScriptConfiguration, $key), ); // Add replace value @@ -124,8 +124,8 @@ protected function getReplaceConfigurationStorage(array $replacerTypoScriptConfi $this->getProcessedValue( $this->typoScriptHelper->findValueOrConfiguration($replaceTypoScriptConfiguration, $key), $replaceTypoScriptConfiguration, - $key - ) + $key, + ), ); $replacerConfigurationStorage->attach($replaceConfiguration); @@ -148,7 +148,7 @@ protected function getProcessedValue($valueOrConfiguration, array $typoScriptCon if ($this->typoScriptHelper->hasStdWrapProperties($typoScriptConfiguration, $key)) { $value = $this->typoScriptHelper->applyStdWrapProperties( $valueOrConfiguration, - $this->typoScriptHelper->getStdWrapProperties($typoScriptConfiguration, $key) + $this->typoScriptHelper->getStdWrapProperties($typoScriptConfiguration, $key), ); } else { $value = $valueOrConfiguration; @@ -156,7 +156,7 @@ protected function getProcessedValue($valueOrConfiguration, array $typoScriptCon } else { $value = $this->typoScriptHelper->applyStdWrapProperties( '', - $valueOrConfiguration + $valueOrConfiguration, ); } @@ -168,13 +168,13 @@ protected function getContentForProcessing(array $processingConfig, string $conf $contentForProcessing = $this->getValueByPath( $processingConfig, - 'search./' . $configurationSearchPointer + 'search./' . $configurationSearchPointer, ); if (ArrayUtility::isValidPath($processingConfig, 'replace./' . $configurationSearchPointer)) { $replaceContentForProcessing = (string)$this->getValueByPath( $processingConfig, - 'replace./' . $configurationSearchPointer + 'replace./' . $configurationSearchPointer, ); // if the replace content for processing is `current` then take the value from search array key if ($replaceContentForProcessing === 'current') { @@ -211,7 +211,7 @@ protected function getConfigurationFor( try { $typoScriptConfiguration = ArrayUtility::getValueByPath( $replacerConfiguration, - (string)$configurationType + (string)$configurationType, ); // We need correct sorting: 10, 10., 20, 30, 30. diff --git a/Classes/Hook/TypoScriptFrontendControllerHook.php b/Classes/Hook/TypoScriptFrontendControllerHook.php index d7da351..9564f3d 100644 --- a/Classes/Hook/TypoScriptFrontendControllerHook.php +++ b/Classes/Hook/TypoScriptFrontendControllerHook.php @@ -36,7 +36,7 @@ public function contentPostProcAll(array &$params, TypoScriptFrontendController } $typoScriptFrontendController->content = $this->replacerHelper->replace( - $typoScriptFrontendController->content + $typoScriptFrontendController->content, ); } } From c830ac3d7ebf2727225fbd5097ab7eaae5619a76 Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Mon, 21 Oct 2024 10:48:53 +0200 Subject: [PATCH 08/13] [TASK] Added version update and changelog in documentation --- Documentation/ChangeLog/Index.rst | 8 ++++++++ Documentation/Settings.cfg | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Documentation/ChangeLog/Index.rst b/Documentation/ChangeLog/Index.rst index c8c6b5d..04517d8 100644 --- a/Documentation/ChangeLog/Index.rst +++ b/Documentation/ChangeLog/Index.rst @@ -7,6 +7,14 @@ ChangeLog ========= +Version 3.0.4 +============= + +* [TASK] Updated TestSuite for GitHub +* [TASK] Formating code lint issues +* [BUGFIX] Handled Type Error when cObj is not ready + + Version 3.0.3 ============= diff --git a/Documentation/Settings.cfg b/Documentation/Settings.cfg index 4072f37..50c6e39 100644 --- a/Documentation/Settings.cfg +++ b/Documentation/Settings.cfg @@ -4,7 +4,7 @@ [general] project = Replacer -version = 3.0.3 +version = 3.0.4 release = 3.0 copyright = by jweiland.net & Contributors From 1c116fa46f66dcdcd59a52acbb67037f4d7e3ff7 Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Mon, 21 Oct 2024 11:21:34 +0200 Subject: [PATCH 09/13] [TASK] Fixed merge conflict rebase --- Classes/Middleware/ReplaceContentMiddleware.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Classes/Middleware/ReplaceContentMiddleware.php b/Classes/Middleware/ReplaceContentMiddleware.php index 841589e..2535987 100644 --- a/Classes/Middleware/ReplaceContentMiddleware.php +++ b/Classes/Middleware/ReplaceContentMiddleware.php @@ -39,9 +39,9 @@ public function __construct(ReplacerHelper $replacerHelper) public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { $response = $handler->handle($request); - if (!$this->getTypoScriptFrontendController()->isINTincScript() - || $response instanceof NullResponse + if ($response instanceof NullResponse || $this->getContentObjectRenderer() === null + || !$this->getTypoScriptFrontendController()->isINTincScript() ) { return $response; } From 3816580c15225c7d56e4fadd11babd1dbf0ceeb4 Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Mon, 21 Oct 2024 11:04:54 +0200 Subject: [PATCH 10/13] [TASK] Updated GitHub workflow file --- .github/workflows/ci.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6efd393..ac6c30e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,9 +37,6 @@ jobs: - name: 'CGL' run: Build/Scripts/runTests.sh -n -p ${{ matrix.php }} -s cgl - - name: 'Execute unit tests' - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s unit - - name: 'Execute functional tests' run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -d mysql -s functional From c46f06d4a952a203ca732b056cd0416fddc4d30f Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Mon, 21 Oct 2024 11:07:56 +0200 Subject: [PATCH 11/13] [TASK] Fixes for trailing_comma_in_multiline CGL --- Classes/Helper/ReplacerHelper.php | 2 +- Tests/Functional/Helper/ReplacerHelperTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Classes/Helper/ReplacerHelper.php b/Classes/Helper/ReplacerHelper.php index ff0f00e..811587f 100644 --- a/Classes/Helper/ReplacerHelper.php +++ b/Classes/Helper/ReplacerHelper.php @@ -206,7 +206,7 @@ protected function processContent(string $content, array $configKey): string protected function getConfigurationFor( array $replacerConfiguration, - ConfigurationTypeEnumeration $configurationType + ConfigurationTypeEnumeration $configurationType, ): array { try { $typoScriptConfiguration = ArrayUtility::getValueByPath( diff --git a/Tests/Functional/Helper/ReplacerHelperTest.php b/Tests/Functional/Helper/ReplacerHelperTest.php index 0ebedfe..ad5558b 100644 --- a/Tests/Functional/Helper/ReplacerHelperTest.php +++ b/Tests/Functional/Helper/ReplacerHelperTest.php @@ -109,7 +109,7 @@ public function replaceContentWithValidSearchAndReplaceValues( array $search, array $replacement, string $contentToReplace, - string $result + string $result, ): void { $config = [ 'config' => [ From 14a3cc5ab9b6e76f660c79fa903526b03d4ce052 Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Mon, 21 Oct 2024 11:15:14 +0200 Subject: [PATCH 12/13] [TASK] Revert trailing_comma_in_multiline fix as methods only support from php 8 --- Classes/Helper/ReplacerHelper.php | 2 +- Tests/Functional/Helper/ReplacerHelperTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Classes/Helper/ReplacerHelper.php b/Classes/Helper/ReplacerHelper.php index 811587f..ff0f00e 100644 --- a/Classes/Helper/ReplacerHelper.php +++ b/Classes/Helper/ReplacerHelper.php @@ -206,7 +206,7 @@ protected function processContent(string $content, array $configKey): string protected function getConfigurationFor( array $replacerConfiguration, - ConfigurationTypeEnumeration $configurationType, + ConfigurationTypeEnumeration $configurationType ): array { try { $typoScriptConfiguration = ArrayUtility::getValueByPath( diff --git a/Tests/Functional/Helper/ReplacerHelperTest.php b/Tests/Functional/Helper/ReplacerHelperTest.php index ad5558b..0ebedfe 100644 --- a/Tests/Functional/Helper/ReplacerHelperTest.php +++ b/Tests/Functional/Helper/ReplacerHelperTest.php @@ -109,7 +109,7 @@ public function replaceContentWithValidSearchAndReplaceValues( array $search, array $replacement, string $contentToReplace, - string $result, + string $result ): void { $config = [ 'config' => [ From 05ca92f6153096833aef9e2b03ff5fda483aca17 Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Mon, 21 Oct 2024 11:16:51 +0200 Subject: [PATCH 13/13] [TASK] Adjust trailing_comma_in_multiline settings --- Build/cgl/.php-cs-fixer.dist.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Build/cgl/.php-cs-fixer.dist.php b/Build/cgl/.php-cs-fixer.dist.php index ee7802f..43584a7 100644 --- a/Build/cgl/.php-cs-fixer.dist.php +++ b/Build/cgl/.php-cs-fixer.dist.php @@ -90,7 +90,7 @@ 'single_line_comment_style' => ['comment_types' => ['hash']], // @todo: Can be dropped once we enable @PER-CS2.0 'single_line_empty_body' => true, - 'trailing_comma_in_multiline' => ['elements' => ['arguments', 'arrays', 'match', 'parameters']], + 'trailing_comma_in_multiline' => ['elements' => ['arrays']], 'whitespace_after_comma_in_array' => ['ensure_single_space' => true], 'yoda_style' => ['equal' => false, 'identical' => false, 'less_and_greater' => false],