From d15c8aafa1a3c5d878f42d6c17417f42859edfe3 Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Wed, 27 Nov 2024 12:20:14 +0100 Subject: [PATCH 01/20] [TASK] Fixed git workflows --- .github/workflows/{typo3_12.yml => ci.yml} | 2 +- .github/workflows/typo3_11.yml | 47 ------------------ Documentation/Settings.cfg | 55 ---------------------- 3 files changed, 1 insertion(+), 103 deletions(-) rename .github/workflows/{typo3_12.yml => ci.yml} (96%) delete mode 100644 .github/workflows/typo3_11.yml delete mode 100644 Documentation/Settings.cfg diff --git a/.github/workflows/typo3_12.yml b/.github/workflows/ci.yml similarity index 96% rename from .github/workflows/typo3_12.yml rename to .github/workflows/ci.yml index 192eb5f..48f5be0 100644 --- a/.github/workflows/typo3_12.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,4 @@ -name: Test sync_crop_areas against TYPO3 12 +name: Tests on: [pull_request] diff --git a/.github/workflows/typo3_11.yml b/.github/workflows/typo3_11.yml deleted file mode 100644 index b5bb616..0000000 --- a/.github/workflows/typo3_11.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: Test sync_crop_areas against TYPO3 11 - -on: [pull_request] - -jobs: - CGL: - name: Coding Style - - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Validate composer.json and composer.lock - run: Build/Scripts/runTests.sh -t 11 -p 8.1 -s composer -e 'validate' - - - name: Install testing system - run: Build/Scripts/runTests.sh -t 11 -p 8.1 -s composerInstall - - - 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 - - testing: - name: PHP Unit and Functional Tests - needs: CGL - - runs-on: ubuntu-latest - - strategy: - fail-fast: false - - matrix: - php: [ '7.4', '8.0', '8.1' ] - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Install testing system - run: Build/Scripts/runTests.sh -t 11 -p ${{ matrix.php }} -s composerInstall - - - name: Functional Tests with mariadb and mysqli - run: Build/Scripts/runTests.sh -t 11 -p ${{ matrix.php }} -d mariadb -a mysqli -s functional diff --git a/Documentation/Settings.cfg b/Documentation/Settings.cfg deleted file mode 100644 index b7e45ef..0000000 --- a/Documentation/Settings.cfg +++ /dev/null @@ -1,55 +0,0 @@ -[general] - -project = Sync Crop Areas -version = 3.0.0 -release = 3.0 -copyright = by jweiland.net - -[html_theme_options] - -# "Edit on GitHub" button -github_repository = jweiland-net/sync-crop-areas -github_branch = main - -# Footer links -project_contact = projects@jweiland.net -project_repository = https://github.com/jweiland-net/sync-crop-areas -project_issues = https://github.com/jweiland-net/sync-crop-areas/issues - -[intersphinx_mapping] - -# Official TYPO3 manuals -h2document = https://docs.typo3.org/m/typo3/docs-how-to-document/main/en-us/ -# t3cheatsheets = https://docs.typo3.org/m/typo3/docs-cheatsheets/main/en-us/ -# t3contribute = https://docs.typo3.org/m/typo3/guide-contributionworkflow/main/en-us/ -t3coreapi = https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ -# t3docteam = https://docs.typo3.org/m/typo3/team-t3docteam/main/en-us/ -# t3editors = https://docs.typo3.org/m/typo3/tutorial-editors/main/en-us/ -# t3extbasebook = https://docs.typo3.org/m/typo3/book-extbasefluid/main/en-us/ -# t3extexample = https://docs.typo3.org/m/typo3/guide-example-extension-manual/main/en-us/ -# t3home = https://docs.typo3.org/ -t3install = https://docs.typo3.org/m/typo3/guide-installation/main/en-us/ -# t3l10n = https://docs.typo3.org/m/typo3/guide-frontendlocalization/main/en-us/ -t3sitepackage = https://docs.typo3.org/m/typo3/tutorial-sitepackage/main/en-us/ -# t3start = https://docs.typo3.org/m/typo3/tutorial-getting-started/main/en-us/ -# t3tca = https://docs.typo3.org/m/typo3/reference-tca/main/en-us/ -# t3templating = https://docs.typo3.org/m/typo3/tutorial-templating/main/en-us/ -# t3translate = https://docs.typo3.org/m/typo3/guide-frontendlocalization/main/en-us/ -# t3tsconfig = https://docs.typo3.org/m/typo3/reference-tsconfig/main/en-us/ -# t3tsref = https://docs.typo3.org/m/typo3/reference-typoscript/main/en-us/ -# t3ts45 = https://docs.typo3.org/m/typo3/tutorial-typoscript-in-45-minutes/main/en-us/ -t3viewhelper = https://docs.typo3.org/other/typo3/view-helper-reference/main/en-us/ -# t3upgrade = https://docs.typo3.org/m/typo3/guide-installation/main/en-us/ - -# TYPO3 system extensions -# ext_adminpanel = https://docs.typo3.org/c/typo3/cms-adminpanel/main/en-us/ -# ext_core = https://docs.typo3.org/c/typo3/cms-core/main/en-us/ -# ext_dashboard = https://docs.typo3.org/c/typo3/cms-dashboard/main/en-us/ -# ext_felogin = https://docs.typo3.org/c/typo3/cms-felogin/main/en-us/ -# ext_form = https://docs.typo3.org/c/typo3/cms-form/main/en-us/ -# ext_fsc = https://docs.typo3.org/c/typo3/cms-fluid-styled-content/main/en-us/ -# ext_indexed_search = https://docs.typo3.org/c/typo3/cms-indexed-search/main/en-us/ -# ext_rte_ckeditor = https://docs.typo3.org/c/typo3/cms-rte-ckeditor/main/en-us/ -# ext_scheduler = https://docs.typo3.org/c/typo3/cms-scheduler/main/en-us/ -# ext_seo = https://docs.typo3.org/c/typo3/cms-seo/main/en-us/ -# ext_workspaces = https://docs.typo3.org/c/typo3/cms-workspaces/main/en-us/ From df9171289735f621d79b0f171b76747032aef9e0 Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Wed, 27 Nov 2024 12:20:33 +0100 Subject: [PATCH 02/20] [TASK] Fixed documentation formats --- Documentation/ChangeLog/Index.rst | 8 ++++++++ Documentation/guides.xml | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 Documentation/guides.xml diff --git a/Documentation/ChangeLog/Index.rst b/Documentation/ChangeLog/Index.rst index 0a3e9f6..e4f79ae 100644 --- a/Documentation/ChangeLog/Index.rst +++ b/Documentation/ChangeLog/Index.rst @@ -7,6 +7,14 @@ ChangeLog ========= +Version 4.0.0 +============= + +* TASK: Add TYPO3 13 compatibility +* TASK: Remove TYPO3 12 compatibility +* TASK: Remove TYPO3 11 compatibility +* TASK: Update Test Suite removing testing docker + Version 3.0.0 ============= diff --git a/Documentation/guides.xml b/Documentation/guides.xml new file mode 100644 index 0000000..366c9bd --- /dev/null +++ b/Documentation/guides.xml @@ -0,0 +1,21 @@ + + + + + + + + + From d745fbcae8e6f45d954bb6493284231edab4d90b Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Wed, 27 Nov 2024 12:20:48 +0100 Subject: [PATCH 03/20] [TASK] Fixed new ersion related infos --- composer.json | 20 ++++++++++++++------ ext_emconf.php | 21 +++++++++++++-------- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/composer.json b/composer.json index 35dfed6..e5d1832 100644 --- a/composer.json +++ b/composer.json @@ -19,22 +19,30 @@ "name": "Stefan Froemken", "email": "sfroemken@jweiland.net", "role": "Lead Developer" + }, + { + "name": "Hoja Mustaffa Abdul Latheef", + "email": "projects@jweiland.net", + "role": "Developer" } ], "support": { "email": "projects@jweiland.net" }, "require": { - "php": "^7.4 || ^8.0", + "php": "^8.2 || ^8.3", "ext-json": "*", - "typo3/cms-core": "^11.5.23 || ^12.4.0" + "typo3/cms-core": "^13.4.0" }, "require-dev": { "sbuerk/typo3-cmscomposerinstallers-testingframework-bridge": "^0.1", - "typo3/testing-framework": "^7.0", - "phpunit/phpunit": "^9.6", - "typo3/coding-standards": "^0.6", - "friendsofphp/php-cs-fixer": "^3.14" + "ergebnis/composer-normalize": "^2.44", + "friendsofphp/php-cs-fixer": "^3.14", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^11.2.5", + "roave/security-advisories": "dev-latest", + "typo3/coding-standards": "^0.8", + "typo3/testing-framework": "^9.0.1" }, "replace": { "typo3-ter/sync_crop_areas": "self.version" diff --git a/ext_emconf.php b/ext_emconf.php index 09ab3fb..d367092 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -1,23 +1,28 @@ 'Sync Crop Areas', 'description' => 'Sync first found crop area to all other CropVariants', - 'version' => '3.0.0', + 'version' => '4.0.0', 'category' => 'plugin', 'state' => 'stable', 'clearCacheOnLoad' => true, - 'author' => 'Stefan Froemken', + 'author' => 'Stefan Froemken, Hoja Mustaffa Abdul Latheef', 'author_email' => 'projects@jweiland.net', 'author_company' => 'jweiland.net', 'constraints' => [ 'depends' => [ - 'php' => '7.4.0-8.99.99', - 'typo3' => '11.5.23-12.4.99', - ], - 'conflicts' => [ - ], - 'suggests' => [ + 'php' => '8.2-8.99.99', + 'typo3' => '13.4.0-13.4.99', ], + 'conflicts' => [], + 'suggests' => [], ], ]; From 4030b415625f7044dac3391d225159eb4182532c Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Wed, 27 Nov 2024 15:38:34 +0100 Subject: [PATCH 04/20] [TASK] Updated Testing Suite --- .github/workflows/ci.yml | 60 +- Build/Scripts/runTests.sh | 702 ++++++++++++--------- Build/cgl/.php-cs-fixer.dist.php | 102 +++ Build/php-cs-fixer/php-cs-fixer.php | 76 --- Build/phpstan/phpstan-baseline.neon | 3 + Build/phpstan/phpstan-typo3-constants.php | 12 + Build/phpstan/phpstan.neon | 19 + Build/phpunit/FunctionalTests.xml | 26 + Build/phpunit/FunctionalTests11.xml | 47 -- Build/phpunit/FunctionalTests12.xml | 44 -- Build/phpunit/FunctionalTestsBootstrap.php | 25 +- Build/phpunit/UnitTests.xml | 26 + Build/phpunit/UnitTests11.xml | 47 -- Build/phpunit/UnitTests12.xml | 46 -- Build/phpunit/UnitTestsBootstrap.php | 84 ++- Build/testing-docker/docker-compose.yml | 370 ----------- 16 files changed, 694 insertions(+), 995 deletions(-) create mode 100644 Build/cgl/.php-cs-fixer.dist.php delete mode 100644 Build/php-cs-fixer/php-cs-fixer.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 delete mode 100644 Build/phpunit/FunctionalTests11.xml delete mode 100644 Build/phpunit/FunctionalTests12.xml create mode 100644 Build/phpunit/UnitTests.xml delete mode 100644 Build/phpunit/UnitTests11.xml delete mode 100644 Build/phpunit/UnitTests12.xml delete mode 100644 Build/testing-docker/docker-compose.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 48f5be0..073b9c8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,45 +3,49 @@ name: Tests on: [pull_request] jobs: - CGL: - name: Coding Style + testing: + name: Testing runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 + strategy: + fail-fast: true - - name: Validate composer.json and composer.lock - run: Build/Scripts/runTests.sh -t 12 -p 8.1 -s composer -e 'validate' + matrix: + php: + - '8.2' + - '8.3' - - name: Install testing system - run: Build/Scripts/runTests.sh -t 12 -p 8.1 -s composerInstall + steps: + - name: 'Checkout' + uses: actions/checkout@v4 - - name: Lint PHP - run: Build/Scripts/runTests.sh -t 12 -p 8.1 -s lint + - name: 'Lint PHP' + run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s lint - - name: Validate code against CGL - run: Build/Scripts/runTests.sh -t 12 -p 8.1 -s cgl -n + - name: 'Install testing system' + run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s composerUpdate - testing: - name: PHP Unit and Functional Tests - needs: CGL + - name: 'Composer validate' + run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s composerValidate - runs-on: ubuntu-latest + - name: 'Composer normalize' + run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s composerNormalize -n - strategy: - fail-fast: false + - name: 'CGL' + run: Build/Scripts/runTests.sh -n -p ${{ matrix.php }} -s cgl - matrix: - php: [ '8.1', '8.2' ] + - name: 'phpstan' + run: Build/Scripts/runTests.sh -n -p ${{ matrix.php }} -s phpstan - steps: - - name: Checkout - uses: actions/checkout@v3 + - 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 - - name: Install testing system - run: Build/Scripts/runTests.sh -t 12 -p ${{ matrix.php }} -s composerInstall + - name: 'Execute functional tests' + run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -d mariadb -s functional - - name: Functional Tests with mariadb and mysqli - run: Build/Scripts/runTests.sh -t 12 -p ${{ matrix.php }} -d mariadb -a mysqli -s functional + - name: 'Execute functional tests' + run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -d postgres -s functional diff --git a/Build/Scripts/runTests.sh b/Build/Scripts/runTests.sh index e38af5d..21e2373 100755 --- a/Build/Scripts/runTests.sh +++ b/Build/Scripts/runTests.sh @@ -1,96 +1,164 @@ #!/usr/bin/env bash # -# TYPO3 core test runner based on docker and docker-compose. +# EXT:examples test runner based on docker/podman. # -# 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}" - echo "MARIADB_VERSION=${MARIADB_VERSION}" - echo "MYSQL_VERSION=${MYSQL_VERSION}" - echo "POSTGRES_VERSION=${POSTGRES_VERSION}" - echo "USED_XDEBUG_MODES=${USED_XDEBUG_MODES}" - echo "IMAGE_PREFIX=${IMAGE_PREFIX}" - } > .env +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" } -# Options -a and -d depend on each other. The function -# validates input combinations and sets defaults. -handleDbmsAndDriverOptions() { +handleDbmsOptions() { + # -a, -d, -i depend on each other. Validate input combinations and set defaults. case ${DBMS} in - mysql|mariadb) + 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 "Invalid combination -d ${DBMS} -a ${DATABASE_DRIVER}" >&2 echo >&2 - echo "call \"./Build/Scripts/runTests.sh -h\" to display help and valid options" >&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 ;; - postgres|sqlite) + 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 option -a ${DATABASE_DRIVER} with -d ${DBMS}" >&2 + 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 "call \"./Build/Scripts/runTests.sh -h\" to display help and valid options" >&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 } -# 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. +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 up build and testing related files - - composer: Execute "composer" command, using -e for command arguments pass-through, ex. -e "ci:php:stan" - - composerInstall: "composer update", handy if host has no PHP - - composerInstallLowest: "composer update", handy if host has no PHP - - composerInstallHighest: "composer update", handy if host has no PHP - - functional: functional tests + - 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 analyze - - phpstanGenerateBaseline: regenerate phpstan baseline, handy after phpstan updates + - 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 acceptance,functional + Only with -s functional|functionalDeprecated Specifies to use another driver, following combinations are available: - mysql - mysqli (default) @@ -100,62 +168,50 @@ Options: - pdo_mysql -d - Only with -s acceptance,functional + Only with -s functional|functionalDeprecated|acceptance|acceptanceComposer|acceptanceInstall Specifies on which DBMS tests are performed - - sqlite: (default) use sqlite + - sqlite: (default): use sqlite - mariadb: use mariadb - - mysql: use mysql + - mysql: use MySQL - postgres: use postgres - -i <10.2|10.3|10.4|10.5|10.6|10.7> - Only with -d mariadb - Specifies on which version of mariadb tests are performed - - 10.2 (default) - - 10.3 - - 10.4 - - 10.5 - - 10.6 - - 10.7 - - -j <5.5|5.6|5.7|8.0> - Only with -d mysql - Specifies on which version of mysql tests are performed - - 5.5 (default) - - 5.6 - - 5.7 - - 8.0 - - -k <10|11|12|13|14> - Only with -d postgres - Specifies on which version of postgres tests are performed - - 10 (default) - - 11 - - 12 - - 13 - - 14 - - -p <7.4|8.0|8.1|8.2> + -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 (default): use PHP 7.4 + - 7.4: 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 functional|unit|composer - 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" + - 8.3: use PHP 8.3 -x - Only with -s functional|unit|acceptance + 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 @@ -164,149 +220,105 @@ Options: Send xdebug information to a different port than default 9003 if an IDE like PhpStorm is not listening on default port. - -z - Only with -x and -s functional|unit|acceptance - This sets the used xdebug modes. Defaults to 'debug,develop' - -n - Only with -s cgl - Activate dry-run in CGL check that does not actively change files and only prints broken ones. + 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 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. + 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 7.4 - ./Build/Scripts/runTests.sh -s unit -EOF + # Run unit tests using PHP 8.2 + ./Build/Scripts/runTests.sh -p 8.2 -s unit -# 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 + # 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 -# Go to directory that contains the local docker-compose.yml file -cd ../testing-docker || exit 1 + # 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 +} -# 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}/../../` +# 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 -TEST_SUITE="" +# 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" -TYPO3_VERSION="11" PHP_XDEBUG_ON=0 PHP_XDEBUG_PORT=9003 -EXTRA_TEST_OPTIONS="" -SCRIPT_VERBOSE=0 -CGLCHECK_DRY_RUN="" -DATABASE_DRIVER="" -MARIADB_VERSION="10.2" -MYSQL_VERSION="5.5" -POSTGRES_VERSION="10" -USED_XDEBUG_MODES="debug,develop" -#@todo the $$ would add the current process id to the name, keeping as plan b -#PROJECT_NAME="runTests-$(basename $(dirname $ROOT_DIR))-$(basename $ROOT_DIR)-$$" -PROJECT_NAME="runTests-$(basename $(dirname $ROOT_DIR))-$(basename $ROOT_DIR)" -PROJECT_NAME="${PROJECT_NAME//[[:blank:]]/}" -echo $PROJECT_NAME - -# Option parsing +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=(); +INVALID_OPTIONS=() # Simple option parsing based on getopts (! not getopt) -while getopts ":s:a:d:i:j:k:p:t:e:xy:z:nhuv" OPT; do +while getopts "a:b:d:i:s:p:xy:nhu" OPT; do case ${OPT} in - s) - TEST_SUITE=${OPTARG} - ;; a) DATABASE_DRIVER=${OPTARG} ;; - d) - DBMS=${OPTARG} + s) + TEST_SUITE=${OPTARG} ;; - i) - MARIADB_VERSION=${OPTARG} - if ! [[ ${MARIADB_VERSION} =~ ^(10.2|10.3|10.4|10.5|10.6|10.7)$ ]]; then + b) + if ! [[ ${OPTARG} =~ ^(docker|podman)$ ]]; then INVALID_OPTIONS+=("${OPTARG}") fi + CONTAINER_BIN=${OPTARG} ;; - j) - MYSQL_VERSION=${OPTARG} - if ! [[ ${MYSQL_VERSION} =~ ^(5.5|5.6|5.7|8.0)$ ]]; then - INVALID_OPTIONS+=("${OPTARG}") - fi + d) + DBMS=${OPTARG} ;; - k) - POSTGRES_VERSION=${OPTARG} - if ! [[ ${POSTGRES_VERSION} =~ ^(10|11|12|13|14)$ ]]; then - INVALID_OPTIONS+=("${OPTARG}") - fi + i) + DBMS_VERSION=${OPTARG} ;; p) PHP_VERSION=${OPTARG} - if ! [[ ${PHP_VERSION} =~ ^(7.4|8.0|8.1|8.2)$ ]]; then + if ! [[ ${PHP_VERSION} =~ ^(7.4|8.0|8.1|8.2|8.3)$ ]]; 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} ;; - z) - USED_XDEBUG_MODES=${OPTARG} + n) + CGLCHECK_DRY_RUN=1 ;; h) + loadHelp echo "${HELP}" exit 0 ;; - n) - CGLCHECK_DRY_RUN="-n" - ;; u) TEST_SUITE=update ;; - v) - SCRIPT_VERBOSE=1 - ;; \?) - INVALID_OPTIONS+=(${OPTARG}) + INVALID_OPTIONS+=("${OPTARG}") ;; :) - INVALID_OPTIONS+=(${OPTARG}) + INVALID_OPTIONS+=("${OPTARG}") ;; esac done @@ -318,171 +330,279 @@ if [ ${#INVALID_OPTIONS[@]} -ne 0 ]; then echo "-"${I} >&2 done echo >&2 - echo "${HELP}" >&2 + echo "call \".Build/Scripts/runTests.sh -h\" to display help and valid options" exit 1 fi -# Move "7.2" to "php72", the latter is the docker container name -DOCKER_PHP_IMAGE=`echo "php${PHP_VERSION}" | sed -e 's/\.//'` +handleDbmsOptions -# Set $1 to first mass argument, this is the optional test file or test directory to execute -shift $((OPTIND - 1)) -TEST_FILE=${1} -if [ -n "${1}" ]; then - TEST_FILE="Web/typo3conf/ext/sync_crop_areas/${1}" - if [ "${TYPO3_VERSION}" == "12" ]; then - TEST_FILE="./${1}" +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 -if [ ${SCRIPT_VERBOSE} -eq 1 ]; then - set -x +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 [ -z ${TEST_SUITE} ]; then - echo "${HELP}" - exit 0 +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) - # Active dry-run for cgl needs not "-n" but specific options - if [[ ! -z ${CGLCHECK_DRY_RUN} ]]; then - CGLCHECK_DRY_RUN="--dry-run --diff" + 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 - setUpDockerComposeDotEnv - docker-compose run cgl + ${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=$? - docker-compose down ;; clean) - rm -rf \ - ../../var/ \ - ../../.cache \ - ../../composer.lock \ - ../../.Build/ \ - ../../Tests/Acceptance/Support/_generated/ \ - ../../composer.json.testing + cleanCacheFiles + cleanRenderedDocumentationFiles + ;; + cleanCache) + cleanCacheFiles + ;; + cleanRenderedDocumentation) + cleanRenderedDocumentationFiles ;; composer) - setUpDockerComposeDotEnv - docker-compose run 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=$? - docker-compose down ;; - composerInstall) - setUpDockerComposeDotEnv - cp ../../composer.json ../../composer.json.orig - if [ -f "../../composer.json.testing" ]; then - cp ../../composer.json ../../composer.json.orig + composerNormalize) + if [ "${CGLCHECK_DRY_RUN}" -eq 1 ]; then + COMMAND=(composer normalize -n) + else + COMMAND=(composer normalize) fi - docker-compose run composer_install - cp ../../composer.json ../../composer.json.testing - mv ../../composer.json.orig ../../composer.json + ${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=$? - docker-compose down ;; - composerInstallLowest) - setUpDockerComposeDotEnv - cp ../../composer.json ../../composer.json.orig - if [ -f "../../composer.json.testing" ]; then - cp ../../composer.json ../../composer.json.orig + 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 - docker-compose run composer_install_lowest - cp ../../composer.json ../../composer.json.testing - mv ../../composer.json.orig ../../composer.json + 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=$? - docker-compose down + cp ${ROOT_DIR}/composer.json ${ROOT_DIR}/composer.json.testing + mv ${ROOT_DIR}/composer.json.orig ${ROOT_DIR}/composer.json ;; - composerInstallHighest) - setUpDockerComposeDotEnv - cp ../../composer.json ../../composer.json.orig - if [ -f "../../composer.json.testing" ]; then - cp ../../composer.json ../../composer.json.orig + 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 - docker-compose run composer_install_highest - cp ../../composer.json ../../composer.json.testing - mv ../../composer.json.orig ../../composer.json + 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=$? - docker-compose down + 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 ;; - coveralls) - setUpDockerComposeDotEnv - docker-compose run coveralls + 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=$? - docker-compose down ;; functional) - handleDbmsAndDriverOptions - setUpDockerComposeDotEnv + 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}" - docker-compose run functional_mariadb + ${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}" - docker-compose run functional_mysql + ${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) - docker-compose run functional_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) - # 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 + # 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=$? ;; - *) - echo "Invalid -d option argument ${DBMS}" >&2 - echo >&2 - echo "${HELP}" >&2 - exit 1 esac - docker-compose down ;; lint) - setUpDockerComposeDotEnv - docker-compose run 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=$? - docker-compose down ;; phpstan) - setUpDockerComposeDotEnv - docker-compose run 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=$? - docker-compose down ;; - phpstanGenerateBaseline) - setUpDockerComposeDotEnv - docker-compose run phpstan_generate_baseline + 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=$? - docker-compose down ;; unit) - setUpDockerComposeDotEnv - docker-compose run 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=$? - 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 {} + # 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 ) - docker images typo3/core-testing-* --filter "dangling=true" --format "{{.ID}}" | xargs -I {} docker rmi {} + 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..9d8ee40 --- /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' => ['arrays']], + '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/php-cs-fixer/php-cs-fixer.php b/Build/php-cs-fixer/php-cs-fixer.php deleted file mode 100644 index ca83e59..0000000 --- a/Build/php-cs-fixer/php-cs-fixer.php +++ /dev/null @@ -1,76 +0,0 @@ -setHeader( - 'This file is part of the package jweiland/sync-crop-areas. - -For the full copyright and license information, please read the -LICENSE file that was distributed with this source code.', - true -); -$config->setFinder( - (new PhpCsFixer\Finder()) - ->in(realpath(__DIR__ . '/../../')) - ->ignoreVCSIgnored(true) - ->notPath('/^.Build\//') - ->notPath('/^Build\/php-cs-fixer\/php-cs-fixer.php/') - ->notPath('/^Build\/phpunit\/(UnitTestsBootstrap|FunctionalTestsBootstrap).php/') - ->notPath('/^Configuration\//') - ->notPath('/^Documentation\//') - ->notName('/^ext_(emconf|localconf|tables).php/') -) - ->setRiskyAllowed(true) - ->setRules([ - '@DoctrineAnnotation' => true, - '@PER' => true, - 'array_syntax' => ['syntax' => 'short'], - 'blank_line_after_opening_tag' => true, - 'braces' => ['allow_single_line_closure' => true], - 'cast_spaces' => ['space' => 'none'], - 'compact_nullable_typehint' => true, - 'concat_space' => ['spacing' => 'one'], - 'declare_equal_normalize' => ['space' => 'none'], - 'dir_constant' => true, - 'function_typehint_space' => true, - 'lowercase_cast' => true, - 'method_argument_space' => ['on_multiline' => 'ensure_fully_multiline'], - '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_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], - ]); -return $config; diff --git a/Build/phpstan/phpstan-baseline.neon b/Build/phpstan/phpstan-baseline.neon new file mode 100644 index 0000000..9e7df65 --- /dev/null +++ b/Build/phpstan/phpstan-baseline.neon @@ -0,0 +1,3 @@ +parameters: + # Ignore specific errors: + ignoreErrors: diff --git a/Build/phpstan/phpstan-typo3-constants.php b/Build/phpstan/phpstan-typo3-constants.php new file mode 100644 index 0000000..28b8d94 --- /dev/null +++ b/Build/phpstan/phpstan-typo3-constants.php @@ -0,0 +1,12 @@ + + + + + + + ../../Tests/Functional/ + + + + + + + diff --git a/Build/phpunit/FunctionalTests11.xml b/Build/phpunit/FunctionalTests11.xml deleted file mode 100644 index cee2ea4..0000000 --- a/Build/phpunit/FunctionalTests11.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - ../../Tests/Functional/ - - - - - - - - - diff --git a/Build/phpunit/FunctionalTests12.xml b/Build/phpunit/FunctionalTests12.xml deleted file mode 100644 index cc83787..0000000 --- a/Build/phpunit/FunctionalTests12.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - ../../Tests/Functional/ - - - - - - - - - diff --git a/Build/phpunit/FunctionalTestsBootstrap.php b/Build/phpunit/FunctionalTestsBootstrap.php index a95bc52..49bc82e 100644 --- a/Build/phpunit/FunctionalTestsBootstrap.php +++ b/Build/phpunit/FunctionalTestsBootstrap.php @@ -1,29 +1,16 @@ 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/UnitTests11.xml b/Build/phpunit/UnitTests11.xml deleted file mode 100644 index 8f1bf61..0000000 --- a/Build/phpunit/UnitTests11.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - ../../Tests/Unit/ - - - - - - - - diff --git a/Build/phpunit/UnitTests12.xml b/Build/phpunit/UnitTests12.xml deleted file mode 100644 index f43f9a3..0000000 --- a/Build/phpunit/UnitTests12.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - ../../Tests/Unit/ - - - - - - - - diff --git a/Build/phpunit/UnitTestsBootstrap.php b/Build/phpunit/UnitTestsBootstrap.php index a4ca910..6266dcb 100644 --- a/Build/phpunit/UnitTestsBootstrap.php +++ b/Build/phpunit/UnitTestsBootstrap.php @@ -1,19 +1,41 @@ 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; - \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::run(0, $requestType, $composerMode); - $testbase->createDirectory(\TYPO3\CMS\Core\Core\Environment::getPublicPath() . '/typo3conf/ext'); - $testbase->createDirectory(\TYPO3\CMS\Core\Core\Environment::getPublicPath() . '/typo3temp/assets'); - $testbase->createDirectory(\TYPO3\CMS\Core\Core\Environment::getPublicPath() . '/typo3temp/var/tests'); - $testbase->createDirectory(\TYPO3\CMS\Core\Core\Environment::getPublicPath() . '/typo3temp/var/transient'); + // @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'; - \TYPO3\CMS\Core\Core\Bootstrap::initializeClassLoader($classLoader); + Bootstrap::initializeClassLoader($classLoader); // Initialize default TYPO3_CONF_VARS - $configurationManager = new \TYPO3\CMS\Core\Configuration\ConfigurationManager(); + $configurationManager = new ConfigurationManager(); $GLOBALS['TYPO3_CONF_VARS'] = $configurationManager->getDefaultConfiguration(); - $cache = new \TYPO3\CMS\Core\Cache\Frontend\PhpFrontend( + $cache = new PhpFrontend( 'core', - new \TYPO3\CMS\Core\Cache\Backend\NullBackend('production', []), + new NullBackend('production', []), ); - // Set all packages to active - $packageManager = \TYPO3\CMS\Core\Core\Bootstrap::createPackageManager( - \TYPO3\CMS\Core\Package\UnitTestPackageManager::class, - \TYPO3\CMS\Core\Core\Bootstrap::createPackageCache($cache) + $packageManager = Bootstrap::createPackageManager( + UnitTestPackageManager::class, + Bootstrap::createPackageCache($cache), ); - \TYPO3\CMS\Core\Utility\GeneralUtility::setSingletonInstance(\TYPO3\CMS\Core\Package\PackageManager::class, $packageManager); - \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::setPackageManager($packageManager); + GeneralUtility::setSingletonInstance(PackageManager::class, $packageManager); + ExtensionManagementUtility::setPackageManager($packageManager); $testbase->dumpClassLoadingInformation(); - \TYPO3\CMS\Core\Utility\GeneralUtility::purgeInstances(); -}); + GeneralUtility::purgeInstances(); +})(); diff --git a/Build/testing-docker/docker-compose.yml b/Build/testing-docker/docker-compose.yml deleted file mode 100644 index 11095c7..0000000 --- a/Build/testing-docker/docker-compose.yml +++ /dev/null @@ -1,370 +0,0 @@ -version: '2.3' -services: - #--------------------------------------------------------------------------------------------------------------------- - # additional services needed for functional tests to be linked, e.g. databases - #--------------------------------------------------------------------------------------------------------------------- - mysql: - image: mysql:${MYSQL_VERSION} - environment: - MYSQL_ROOT_PASSWORD: funcp - tmpfs: - - /var/lib/mysql/:rw,noexec,nosuid - - mariadb: - image: mariadb:${MARIADB_VERSION} - environment: - MYSQL_ROOT_PASSWORD: funcp - tmpfs: - - /var/lib/mysql/:rw,noexec,nosuid - - postgres: - image: postgres:${POSTGRES_VERSION}-alpine - environment: - POSTGRES_PASSWORD: funcp - POSTGRES_USER: ${HOST_USER} - tmpfs: - - /var/lib/postgresql/data:rw,noexec,nosuid - - #--------------------------------------------------------------------------------------------------------------------- - # composer related services - #--------------------------------------------------------------------------------------------------------------------- - composer: - image: typo3/core-testing-${DOCKER_PHP_IMAGE}:latest - user: "${HOST_UID}" - volumes: - - ${ROOT_DIR}:${ROOT_DIR} - working_dir: ${ROOT_DIR} - environment: - COMPOSER_HOME: ".cache/composer-home" - COMPOSER_CACHE_DIR: ".cache/composer" - command: > - /bin/sh -c " - if [ ${SCRIPT_VERBOSE} -eq 1 ]; then - set -x - fi - php -v | grep '^PHP'; - composer ${EXTRA_TEST_OPTIONS}; - " - - composer_install: - image: typo3/core-testing-${DOCKER_PHP_IMAGE}:latest - user: "${HOST_UID}" - volumes: - - ${ROOT_DIR}:${ROOT_DIR} - working_dir: ${ROOT_DIR} - environment: - COMPOSER_HOME: ".cache/composer-home" - 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 require --no-ansi --no-interaction --no-progress --no-install typo3/cms-core:^11.5.24 - fi - if [ ${TYPO3_VERSION} -eq 12 ]; then - composer require --no-ansi --no-interaction --no-progress --no-install typo3/cms-core:^12.2 - fi - composer install --no-progress; - " - - composer_install_lowest: - image: typo3/core-testing-${DOCKER_PHP_IMAGE}:latest - user: "${HOST_UID}" - volumes: - - ${ROOT_DIR}:${ROOT_DIR} - working_dir: ${ROOT_DIR} - environment: - COMPOSER_HOME: ".cache/composer-home" - 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 require --no-ansi --no-interaction --no-progress --no-install typo3/cms-core:^11.5.24 - fi - if [ ${TYPO3_VERSION} -eq 12 ]; then - composer require --no-ansi --no-interaction --no-progress --no-install typo3/cms-core:^12.0 - fi - composer update --no-ansi --no-interaction --no-progress --with-dependencies --prefer-lowest; - composer show; - " - - composer_install_highest: - image: typo3/core-testing-${DOCKER_PHP_IMAGE}:latest - user: "${HOST_UID}" - volumes: - - ${ROOT_DIR}:${ROOT_DIR} - working_dir: ${ROOT_DIR} - environment: - COMPOSER_HOME: ".cache/composer-home" - COMPOSER_CACHE_DIR: ".cache/composer" - command: > - /bin/sh -c " - if [ ${SCRIPT_VERBOSE} -eq 1 ]; then - set -x - fi - if [ ${TYPO3_VERSION} -eq 11 ]; then - composer require --no-ansi --no-interaction --no-progress --no-install typo3/cms-core:^11.5.24 - fi - if [ ${TYPO3_VERSION} -eq 12 ]; then - composer require --no-ansi --no-interaction --no-progress --no-install typo3/cms-core:^12.2 - fi - composer update --no-progress --no-interaction; - composer show; - " - - #--------------------------------------------------------------------------------------------------------------------- - # Unit tests - #--------------------------------------------------------------------------------------------------------------------- - 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/phpunit/UnitTests${TYPO3_VERSION}.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/phpunit/UnitTests${TYPO3_VERSION}.xml ${EXTRA_TEST_OPTIONS} ${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 - " - - #--------------------------------------------------------------------------------------------------------------------- - # functional tests against different dbms - #--------------------------------------------------------------------------------------------------------------------- - 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/phpunit/FunctionalTests${TYPO3_VERSION}.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/phpunit/FunctionalTests${TYPO3_VERSION}.xml ${EXTRA_TEST_OPTIONS} --exclude-group not-sqlite ${TEST_FILE}; - fi - " - - functional_postgres: - image: typo3/core-testing-${DOCKER_PHP_IMAGE}:latest - user: "${HOST_UID}" - links: - - postgres - volumes: - - ${ROOT_DIR}:${ROOT_DIR} - environment: - typo3DatabaseDriver: pdo_pgsql - typo3DatabaseName: bamboo - typo3DatabaseUsername: ${HOST_USER} - typo3DatabaseHost: postgres - 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 postgres 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/phpunit/FunctionalTests${TYPO3_VERSION}.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/phpunit/FunctionalTests${TYPO3_VERSION}.xml ${EXTRA_TEST_OPTIONS} --exclude-group not-postgres ${TEST_FILE}; - fi - " - - functional_mysql: - image: typo3/core-testing-${DOCKER_PHP_IMAGE}:latest - user: "${HOST_UID}" - links: - - mysql - volumes: - - ${ROOT_DIR}:${ROOT_DIR} - environment: - typo3DatabaseDriver: "${DATABASE_DRIVER}" - typo3DatabaseName: func_test - typo3DatabaseUsername: root - typo3DatabasePassword: funcp - typo3DatabaseHost: mysql - 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 mysql 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/phpunit/FunctionalTests${TYPO3_VERSION}.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/phpunit/FunctionalTests${TYPO3_VERSION}.xml ${EXTRA_TEST_OPTIONS} ${TEST_FILE}; - fi - " - - functional_mariadb: - image: typo3/core-testing-${DOCKER_PHP_IMAGE}:latest - user: "${HOST_UID}" - links: - - mariadb - volumes: - - ${ROOT_DIR}:${ROOT_DIR} - environment: - typo3DatabaseDriver: "${DATABASE_DRIVER}" - typo3DatabaseName: func_test - typo3DatabaseUsername: root - typo3DatabasePassword: funcp - typo3DatabaseHost: mariadb - 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 mariadb 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/phpunit/FunctionalTests${TYPO3_VERSION}.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/phpunit/FunctionalTests${TYPO3_VERSION}.xml ${EXTRA_TEST_OPTIONS} ${TEST_FILE}; - fi - " - - #--------------------------------------------------------------------------------------------------------------------- - # code quality tools - #--------------------------------------------------------------------------------------------------------------------- - 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/php-cs-fixer.php --using-cache=no . - 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/php-cs-fixer.php --using-cache=no . - fi - " - - 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/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/phpstan.neon --generate-baseline=Build/phpstan/phpstan-baseline.neon - " - - 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-backend:^11.5 typo3/cms-recordlist:^11.5 typo3/cms-frontend:^11.5 typo3/cms-extbase:^11.5 typo3/cms-fluid:^11.5 typo3/cms-install:^11.5 phpunit/phpunit:^9.6.4 - 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-backend:~12.4 typo3/cms-recordlist:~12.4 typo3/cms-frontend:~12.4 typo3/cms-extbase:~12.4 typo3/cms-fluid:~12.4 typo3/cms-install:~12.4 phpunit/phpunit:^10 - composer req typo3/cms-core:~12.4 -W --no-update - fi - composer update --no-progress --no-interaction; - " From e5de00487e8d48d596087f399ae395a1ab4dc65e Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Wed, 27 Nov 2024 15:40:00 +0100 Subject: [PATCH 05/20] [TASK] Fixed Code formatting --- .../SynchronizeCropVariantsCommand.php | 30 +++++++++---------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/Classes/Command/SynchronizeCropVariantsCommand.php b/Classes/Command/SynchronizeCropVariantsCommand.php index 4783286..33da038 100644 --- a/Classes/Command/SynchronizeCropVariantsCommand.php +++ b/Classes/Command/SynchronizeCropVariantsCommand.php @@ -13,6 +13,7 @@ use Doctrine\DBAL\Result; use JWeiland\SyncCropAreas\Service\UpdateCropVariantsService; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -20,23 +21,19 @@ use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction; use TYPO3\CMS\Core\Utility\GeneralUtility; -/** - * Use this service to synchronize first found cropVariants to the other defined cropVariants - */ -class SynchronizeCropVariantsCommand extends Command +#[AsCommand( + name: 'sync_crop_areas:sync', + description: 'Use this service to synchronize first found cropVariants to the other defined cropVariants', +)] +final class SynchronizeCropVariantsCommand extends Command { protected OutputInterface $output; - protected UpdateCropVariantsService $updateCropVariantsService; - - /* - * Will be called by DI, so please don't add extbase classes with inject methods here. - */ - public function __construct(UpdateCropVariantsService $updateCropVariantsService, string $name = null) - { + public function __construct( + protected UpdateCropVariantsService $updateCropVariantsService, + string $name = null + ) { parent::__construct($name); - - $this->updateCropVariantsService = $updateCropVariantsService; } protected function configure(): void @@ -58,13 +55,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int $output->writeln('Start synchronizing crop variants of table sys_file_reference'); [$counter, $processed, $skipped] = $this->synchronizeCropVariants(); $output->writeln(sprintf( - 'We had %d sys_file_reference records in total. %d records were processed successfully and %d records must be skipped because of invalid values', + 'We had %d sys_file_reference records in total. %d records were processed successfully and %d records ' . + 'must be skipped because of invalid values', $counter, $processed, $skipped )); - return 0; + return Command::SUCCESS; } protected function synchronizeCropVariants(): array @@ -139,7 +137,7 @@ protected function getStatementForSysFileReferences(): Result ->where( $queryBuilder->expr()->eq( 'sync_crop_area', - $queryBuilder->createNamedParameter(1, \PDO::PARAM_INT) + $queryBuilder->createNamedParameter(1) ) ) ->executeQuery(); From 0dbed5bfee89487ad5d518808173c02ef5bc374e Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Wed, 27 Nov 2024 15:40:50 +0100 Subject: [PATCH 06/20] [TASK] Removed default option and added description --- Configuration/Services.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml index 3ff0856..b56f52a 100644 --- a/Configuration/Services.yaml +++ b/Configuration/Services.yaml @@ -15,4 +15,4 @@ services: tags: - name: 'console.command' command: 'sync_crop_areas:sync' - schedulable: true + description: 'Use this service to synchronize first found cropVariants to the other defined cropVariants' From 0cd366acf904df876f681846b3430fadcc600c38 Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Wed, 27 Nov 2024 15:41:57 +0100 Subject: [PATCH 07/20] [TASK] Added HeaderComment --- Configuration/TCA/Overrides/sys_file_reference.php | 7 +++++++ ext_emconf.php | 2 +- ext_localconf.php | 7 +++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Configuration/TCA/Overrides/sys_file_reference.php b/Configuration/TCA/Overrides/sys_file_reference.php index 4fd0a9a..79b1368 100644 --- a/Configuration/TCA/Overrides/sys_file_reference.php +++ b/Configuration/TCA/Overrides/sys_file_reference.php @@ -1,5 +1,12 @@ Date: Wed, 27 Nov 2024 15:42:26 +0100 Subject: [PATCH 08/20] [TASK] Composer Normalized fixes --- composer.json | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index e5d1832..b157aac 100644 --- a/composer.json +++ b/composer.json @@ -1,8 +1,8 @@ { "name": "jweiland/sync-crop-areas", - "type": "typo3-cms-extension", "description": "Sync first found crop area to all other CropVariants", "license": "GPL-2.0-or-later", + "type": "typo3-cms-extension", "keywords": [ "typo3", "TYPO3 CMS", @@ -13,7 +13,6 @@ "area", "variants" ], - "homepage": "https://jweiland.net", "authors": [ { "name": "Stefan Froemken", @@ -26,21 +25,22 @@ "role": "Developer" } ], + "homepage": "https://jweiland.net", "support": { "email": "projects@jweiland.net" }, "require": { - "php": "^8.2 || ^8.3", + "php": "^8.2", "ext-json": "*", "typo3/cms-core": "^13.4.0" }, "require-dev": { - "sbuerk/typo3-cmscomposerinstallers-testingframework-bridge": "^0.1", "ergebnis/composer-normalize": "^2.44", "friendsofphp/php-cs-fixer": "^3.14", "phpstan/phpstan": "^1.10", "phpunit/phpunit": "^11.2.5", "roave/security-advisories": "dev-latest", + "sbuerk/typo3-cmscomposerinstallers-testingframework-bridge": "^0.1", "typo3/coding-standards": "^0.8", "typo3/testing-framework": "^9.0.1" }, @@ -58,17 +58,18 @@ } }, "config": { - "vendor-dir": ".Build/vendor", - "bin-dir": ".Build/bin", "allow-plugins": { + "ergebnis/composer-normalize": true, "typo3/class-alias-loader": true, "typo3/cms-composer-installers": true - } + }, + "bin-dir": ".Build/bin", + "vendor-dir": ".Build/vendor" }, "extra": { "typo3/cms": { - "extension-key": "sync_crop_areas", "app-dir": ".Build", + "extension-key": "sync_crop_areas", "web-dir": ".Build/Web" } } From 63e18f25ac4c1bbee4e383747f97a89f6124da64 Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Fri, 29 Nov 2024 07:51:48 +0100 Subject: [PATCH 09/20] [TASK] Fixed functional test cases --- .../SynchronizeCropVariantsCommandTest.php | 70 +++++++++++-------- Tests/Functional/Hook/DataHandlerHookTest.php | 16 +++-- .../Service/UpdateCropVariantsServiceTest.php | 2 +- 3 files changed, 49 insertions(+), 39 deletions(-) diff --git a/Tests/Functional/Command/SynchronizeCropVariantsCommandTest.php b/Tests/Functional/Command/SynchronizeCropVariantsCommandTest.php index 5684b8c..b0c9549 100644 --- a/Tests/Functional/Command/SynchronizeCropVariantsCommandTest.php +++ b/Tests/Functional/Command/SynchronizeCropVariantsCommandTest.php @@ -78,12 +78,20 @@ protected function tearDown(): void public function runWithNoSysFileReferencesDisplaysEmptyStatistic(): void { $this->outputMock - ->expects(self::exactly(2)) + ->expects($this->exactly(2)) ->method('writeln') - ->willReturnOnConsecutiveCalls([ - ['Start synchronizing crop variants of table sys_file_reference', null], - ['We had 0 sys_file_reference records in total. 0 records were processed successfully and 0 records must be skipped because of invalid values', null], - ]); + ->with($this->callback(function ($output) { + static $calls = 0; + $expectedOutputs = [ + 'Start synchronizing crop variants of table sys_file_reference', + 'We had 0 sys_file_reference records in total. 0 records were processed successfully and 0 records must be skipped because of invalid values' + ]; + + // Assert each call matches the expected output + $this->assertEquals($expectedOutputs[$calls], $output); + $calls++; + return true; + })); $this->subject->run( $this->inputMock, @@ -113,13 +121,13 @@ public function runWithEmptyCropColumnWillSkipRecord(): void ); $this->outputMock - ->expects(self::exactly(3)) + ->expects($this->exactly(3)) ->method('writeln') - ->willReturnOnConsecutiveCalls([ - ['Start synchronizing crop variants of table sys_file_reference', null], - ['SKIP: Column "crop" of sys_file_reference record with UID 1 is empty', null], - ['We had 1 sys_file_reference records in total. 0 records were processed successfully and 1 records must be skipped because of invalid values', null], - ]); + ->willReturnOnConsecutiveCalls( + 'Start synchronizing crop variants of table sys_file_reference', + 'SKIP: Column "crop" of sys_file_reference record with UID 1 is empty', + 'We had 1 sys_file_reference records in total. 0 records were processed successfully and 1 records must be skipped because of invalid values', + ); $this->subject->run( $this->inputMock, @@ -149,13 +157,13 @@ public function runWithEmptyPidColumnWillSkipRecord(): void ); $this->outputMock - ->expects(self::exactly(3)) + ->expects($this->exactly(3)) ->method('writeln') - ->willReturnOnConsecutiveCalls([ - ['Start synchronizing crop variants of table sys_file_reference', null], - ['SKIP: Column "pid" of sys_file_reference record with UID 1 is empty', null], - ['We had 1 sys_file_reference records in total. 0 records were processed successfully and 1 records must be skipped because of invalid values', null], - ]); + ->willReturnOnConsecutiveCalls( + 'Start synchronizing crop variants of table sys_file_reference', + 'SKIP: Column "pid" of sys_file_reference record with UID 1 is empty', + 'We had 1 sys_file_reference records in total. 0 records were processed successfully and 1 records must be skipped because of invalid values', + ); $this->subject->run( $this->inputMock, @@ -187,16 +195,16 @@ public function runWithUnchangedCropWillSkipRecord(): void ); $this->outputMock - ->expects(self::exactly(3)) + ->expects($this->exactly(3)) ->method('writeln') - ->willReturnOnConsecutiveCalls([ - ['Start synchronizing crop variants of table sys_file_reference', null], - ['SKIP: Column "crop" of table "sys_file_reference" with UID 1 because it is unchanged, empty or invalid JSON', null], - ['We had 1 sys_file_reference records in total. 0 records were processed successfully and 1 records must be skipped because of invalid values', null], - ]); + ->willReturnOnConsecutiveCalls( + 'Start synchronizing crop variants of table sys_file_reference', + 'SKIP: Column "crop" of table "sys_file_reference" with UID 1 because it is unchanged, empty or invalid JSON', + 'We had 1 sys_file_reference records in total. 0 records were processed successfully and 1 records must be skipped because of invalid values', + ); $this->updateCropVariantsServiceMock - ->expects(self::atLeastOnce()) + ->expects($this->atLeastOnce()) ->method('synchronizeCropVariants') ->willReturn($sysFileReferenceRecord); @@ -215,15 +223,15 @@ public function runWithChangedCropWillUpdateRecord(): void $this->importCSVDataSet(__DIR__ . '/../Fixtures/sys_file_reference.csv'); $this->outputMock - ->expects(self::exactly(2)) + ->expects($this->exactly(2)) ->method('writeln') - ->willReturnOnConsecutiveCalls([ - ['Start synchronizing crop variants of table sys_file_reference', null], - ['We had 3 sys_file_reference records in total. 3 records were processed successfully and 0 records must be skipped because of invalid values', null], - ]); + ->willReturnOnConsecutiveCalls( + 'Start synchronizing crop variants of table sys_file_reference', + 'We had 3 sys_file_reference records in total. 3 records were processed successfully and 0 records must be skipped because of invalid values', + ); $this->updateCropVariantsServiceMock - ->expects(self::atLeastOnce()) + ->expects($this->atLeastOnce()) ->method('synchronizeCropVariants') ->willReturn(['crop' => '{foo: "bar"}']); @@ -234,7 +242,7 @@ public function runWithChangedCropWillUpdateRecord(): void $connection = $this->getConnectionPool()->getConnectionForTable('sys_file_reference'); $statement = $connection->select(['*'], 'sys_file_reference'); - while ($updatedRecord = $statement->fetch()) { + while ($updatedRecord = $statement->fetchAssociative()) { self::assertSame( '{foo: "bar"}', $updatedRecord['crop'] diff --git a/Tests/Functional/Hook/DataHandlerHookTest.php b/Tests/Functional/Hook/DataHandlerHookTest.php index 01223dd..3088491 100644 --- a/Tests/Functional/Hook/DataHandlerHookTest.php +++ b/Tests/Functional/Hook/DataHandlerHookTest.php @@ -11,6 +11,7 @@ namespace JWeiland\SyncCropAreas\Tests\Functional\Hook; +use Doctrine\DBAL\Exception; use JWeiland\SyncCropAreas\Helper\TcaHelper; use JWeiland\SyncCropAreas\Hook\DataHandlerHook; use JWeiland\SyncCropAreas\Service\UpdateCropVariantsService; @@ -69,7 +70,7 @@ protected function tearDown(): void public function hookWithEmptyDatamapWillNotProcessAnything(): void { $this->tcaHelperMock - ->expects(self::never()) + ->expects($this->never()) ->method('getColumnsWithFileReferences'); /** @var DataHandler|MockObject $dataHandlerMock */ @@ -88,7 +89,7 @@ public function hookWithEmptyDatamapWillNotProcessAnything(): void public function hookWithoutSysFileReferenceWillNotProcessAnything(): void { $this->tcaHelperMock - ->expects(self::never()) + ->expects($this->never()) ->method('getColumnsWithFileReferences'); /** @var DataHandler|MockObject $dataHandlerMock */ @@ -107,7 +108,7 @@ public function hookWithoutSysFileReferenceWillNotProcessAnything(): void $this->subject->processDatamap_afterAllOperations($dataHandler); } - public function dataProviderForInvalidFileTables(): array + public static function dataProviderForInvalidFileTables(): array { return [ 'Do not process sys_file records' => ['sys_file'], @@ -128,7 +129,7 @@ public function dataProviderForInvalidFileTables(): array public function hookWithOnlyFileTablesWillNotProcessAnything(string $invalidTable): void { $this->tcaHelperMock - ->expects(self::never()) + ->expects($this->never()) ->method('getColumnsWithFileReferences'); /** @var DataHandler|MockObject $dataHandlerMock */ @@ -149,6 +150,7 @@ public function hookWithOnlyFileTablesWillNotProcessAnything(string $invalidTabl /** * @test + * @throws Exception */ public function hookWillUpdateSysFileReferenceRecords(): void { @@ -156,13 +158,13 @@ public function hookWillUpdateSysFileReferenceRecords(): void $this->importCSVDataSet(__DIR__ . '/../Fixtures/sys_file_reference.csv'); $this->tcaHelperMock - ->expects(self::atLeastOnce()) + ->expects($this->atLeastOnce()) ->method('getColumnsWithFileReferences') ->with(self::identicalTo('tt_content')) ->willReturn(['image']); $this->updateCropVariantsServiceMock - ->expects(self::exactly(3)) + ->expects($this->exactly(3)) ->method('synchronizeCropVariants') ->willReturnCallback(static function (array $sysFileReferenceRecord) { self::assertArrayHasKey('uid', $sysFileReferenceRecord); @@ -201,7 +203,7 @@ public function hookWillUpdateSysFileReferenceRecords(): void $connection = $this->getConnectionPool()->getConnectionForTable('sys_file_reference'); $statement = $connection->select(['*'], 'sys_file_reference'); - while ($updatedRecord = $statement->fetch()) { + while ($updatedRecord = $statement->fetchAssociative()) { self::assertSame( '{foo: "bar"}', $updatedRecord['crop'] diff --git a/Tests/Functional/Service/UpdateCropVariantsServiceTest.php b/Tests/Functional/Service/UpdateCropVariantsServiceTest.php index 21c62bc..73ab7a6 100644 --- a/Tests/Functional/Service/UpdateCropVariantsServiceTest.php +++ b/Tests/Functional/Service/UpdateCropVariantsServiceTest.php @@ -246,7 +246,7 @@ public function synchronizeCropVariantsWithDeactivatedFeatureWillNotChangeRecord ); } - public function invalidSysFileReferenceDataProvider(): array + public static function invalidSysFileReferenceDataProvider(): array { return [ 'Missing sync_crop_area column' => [['crop' => '{}', 'tablenames' => 'a', 'fieldname' => 'b', 'uid_foreign' => 1, 'pid' => 2]], From c1231b1bfb355ea10a7d692fd94ba7a7894240b1 Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Fri, 29 Nov 2024 07:59:32 +0100 Subject: [PATCH 10/20] [TASK] Updated README file --- README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/README.md b/README.md index 35bf021..407f600 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,13 @@ # TYPO3 Extension `sync_crop_areas` +[![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 13.4][TYPO3-shield]][TYPO3-13-url] + +![Build Status](https://github.com/jweiland-net/sync_crop_areas/actions/workflows/ci.yml/badge.svg) ## What does it do? e, if you want to copy the crop area of first crop variant over to all other crop @@ -27,3 +35,24 @@ Import the extension from TER (TYPO3 Extension Repository) There is no configuration for this extensions. Just save the content (tt_content) record to sync the cropAreas over all cropVariants + + + + +[extension-build-shield]: https://poser.pugx.org/jweiland/sync-crop-areas/v/stable.svg?style=for-the-badge + +[extension-downloads-badge]: https://poser.pugx.org/jweiland/sync-crop-areas/d/total.svg?style=for-the-badge + +[extension-monthly-downloads]: https://poser.pugx.org/jweiland/sync-crop-areas/d/monthly?style=for-the-badge + +[extension-ter-url]: https://extensions.typo3.org/extension/sync_crop_areas/ + +[extension-packagist-url]: https://packagist.org/packages/jweiland/sync-crop-areas/ + +[packagist-logo-stable]: https://img.shields.io/badge/--grey.svg?style=for-the-badge&logo=packagist&logoColor=white + +[TYPO3-13-url]: https://get.typo3.org/version/13 + +[TYPO3-shield]: https://img.shields.io/badge/TYPO3-13.4-green.svg?style=for-the-badge&logo=typo3 + +[LICENSE_BADGE]: https://img.shields.io/github/license/jweiland-net/sync_crop_areas?label=license&style=for-the-badge From af03e40fa7dd360450bd7607b94d9d74461b47cb Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Fri, 29 Nov 2024 08:05:24 +0100 Subject: [PATCH 11/20] [TASK] Fixed CGL issues --- .../SynchronizeCropVariantsCommandTest.php | 18 +++++++++--------- Tests/Functional/Hook/DataHandlerHookTest.php | 10 +++++----- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Tests/Functional/Command/SynchronizeCropVariantsCommandTest.php b/Tests/Functional/Command/SynchronizeCropVariantsCommandTest.php index b0c9549..cc93d8e 100644 --- a/Tests/Functional/Command/SynchronizeCropVariantsCommandTest.php +++ b/Tests/Functional/Command/SynchronizeCropVariantsCommandTest.php @@ -78,13 +78,13 @@ protected function tearDown(): void public function runWithNoSysFileReferencesDisplaysEmptyStatistic(): void { $this->outputMock - ->expects($this->exactly(2)) + ->expects(self::exactly(2)) ->method('writeln') - ->with($this->callback(function ($output) { + ->with(self::callback(function ($output) { static $calls = 0; $expectedOutputs = [ 'Start synchronizing crop variants of table sys_file_reference', - 'We had 0 sys_file_reference records in total. 0 records were processed successfully and 0 records must be skipped because of invalid values' + 'We had 0 sys_file_reference records in total. 0 records were processed successfully and 0 records must be skipped because of invalid values', ]; // Assert each call matches the expected output @@ -121,7 +121,7 @@ public function runWithEmptyCropColumnWillSkipRecord(): void ); $this->outputMock - ->expects($this->exactly(3)) + ->expects(self::exactly(3)) ->method('writeln') ->willReturnOnConsecutiveCalls( 'Start synchronizing crop variants of table sys_file_reference', @@ -157,7 +157,7 @@ public function runWithEmptyPidColumnWillSkipRecord(): void ); $this->outputMock - ->expects($this->exactly(3)) + ->expects(self::exactly(3)) ->method('writeln') ->willReturnOnConsecutiveCalls( 'Start synchronizing crop variants of table sys_file_reference', @@ -195,7 +195,7 @@ public function runWithUnchangedCropWillSkipRecord(): void ); $this->outputMock - ->expects($this->exactly(3)) + ->expects(self::exactly(3)) ->method('writeln') ->willReturnOnConsecutiveCalls( 'Start synchronizing crop variants of table sys_file_reference', @@ -204,7 +204,7 @@ public function runWithUnchangedCropWillSkipRecord(): void ); $this->updateCropVariantsServiceMock - ->expects($this->atLeastOnce()) + ->expects(self::atLeastOnce()) ->method('synchronizeCropVariants') ->willReturn($sysFileReferenceRecord); @@ -223,7 +223,7 @@ public function runWithChangedCropWillUpdateRecord(): void $this->importCSVDataSet(__DIR__ . '/../Fixtures/sys_file_reference.csv'); $this->outputMock - ->expects($this->exactly(2)) + ->expects(self::exactly(2)) ->method('writeln') ->willReturnOnConsecutiveCalls( 'Start synchronizing crop variants of table sys_file_reference', @@ -231,7 +231,7 @@ public function runWithChangedCropWillUpdateRecord(): void ); $this->updateCropVariantsServiceMock - ->expects($this->atLeastOnce()) + ->expects(self::atLeastOnce()) ->method('synchronizeCropVariants') ->willReturn(['crop' => '{foo: "bar"}']); diff --git a/Tests/Functional/Hook/DataHandlerHookTest.php b/Tests/Functional/Hook/DataHandlerHookTest.php index 3088491..19dd142 100644 --- a/Tests/Functional/Hook/DataHandlerHookTest.php +++ b/Tests/Functional/Hook/DataHandlerHookTest.php @@ -70,7 +70,7 @@ protected function tearDown(): void public function hookWithEmptyDatamapWillNotProcessAnything(): void { $this->tcaHelperMock - ->expects($this->never()) + ->expects(self::never()) ->method('getColumnsWithFileReferences'); /** @var DataHandler|MockObject $dataHandlerMock */ @@ -89,7 +89,7 @@ public function hookWithEmptyDatamapWillNotProcessAnything(): void public function hookWithoutSysFileReferenceWillNotProcessAnything(): void { $this->tcaHelperMock - ->expects($this->never()) + ->expects(self::never()) ->method('getColumnsWithFileReferences'); /** @var DataHandler|MockObject $dataHandlerMock */ @@ -129,7 +129,7 @@ public static function dataProviderForInvalidFileTables(): array public function hookWithOnlyFileTablesWillNotProcessAnything(string $invalidTable): void { $this->tcaHelperMock - ->expects($this->never()) + ->expects(self::never()) ->method('getColumnsWithFileReferences'); /** @var DataHandler|MockObject $dataHandlerMock */ @@ -158,13 +158,13 @@ public function hookWillUpdateSysFileReferenceRecords(): void $this->importCSVDataSet(__DIR__ . '/../Fixtures/sys_file_reference.csv'); $this->tcaHelperMock - ->expects($this->atLeastOnce()) + ->expects(self::atLeastOnce()) ->method('getColumnsWithFileReferences') ->with(self::identicalTo('tt_content')) ->willReturn(['image']); $this->updateCropVariantsServiceMock - ->expects($this->exactly(3)) + ->expects(self::exactly(3)) ->method('synchronizeCropVariants') ->willReturnCallback(static function (array $sysFileReferenceRecord) { self::assertArrayHasKey('uid', $sysFileReferenceRecord); From 551be55788810a1666dff09f53f922e0cf235a96 Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Fri, 29 Nov 2024 08:40:15 +0100 Subject: [PATCH 12/20] [TASK] Removed phpstan --- .github/workflows/ci.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 073b9c8..2bbb1ec 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,9 +35,6 @@ jobs: - name: 'CGL' run: Build/Scripts/runTests.sh -n -p ${{ matrix.php }} -s cgl - - name: 'phpstan' - run: Build/Scripts/runTests.sh -n -p ${{ matrix.php }} -s phpstan - - name: 'Execute unit tests' run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s unit From 87d1bb6cb706f047b4c5e16a3e1125c82032368b Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Fri, 29 Nov 2024 08:41:28 +0100 Subject: [PATCH 13/20] [TASK] Removed Unit Tests --- .github/workflows/ci.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2bbb1ec..7e40622 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,9 +35,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 65407cdccf051cde40a5ef08810858efb65aea80 Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef <144037456+hojalatheef@users.noreply.github.com> Date: Mon, 2 Dec 2024 09:45:31 +0100 Subject: [PATCH 14/20] Update Build/phpstan/phpstan.neon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Stefan Frömken <123929835+sfroemkenjw@users.noreply.github.com> --- Build/phpstan/phpstan.neon | 1 + 1 file changed, 1 insertion(+) diff --git a/Build/phpstan/phpstan.neon b/Build/phpstan/phpstan.neon index a43b6a4..c40eb8e 100644 --- a/Build/phpstan/phpstan.neon +++ b/Build/phpstan/phpstan.neon @@ -1,5 +1,6 @@ includes: - phpstan-baseline.neon + parameters: level: 6 From 26af1b7505c53b8318ea1fb6b199e37248123f49 Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef <144037456+hojalatheef@users.noreply.github.com> Date: Mon, 2 Dec 2024 09:45:55 +0100 Subject: [PATCH 15/20] Update Build/phpstan/phpstan-baseline.neon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Stefan Frömken <123929835+sfroemkenjw@users.noreply.github.com> --- Build/phpstan/phpstan-baseline.neon | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Build/phpstan/phpstan-baseline.neon b/Build/phpstan/phpstan-baseline.neon index 9e7df65..542bfa4 100644 --- a/Build/phpstan/phpstan-baseline.neon +++ b/Build/phpstan/phpstan-baseline.neon @@ -1,3 +1,3 @@ parameters: - # Ignore specific errors: - ignoreErrors: + # Ignore specific errors: + ignoreErrors: From ec12ab9ace25fd9a1652f2e2932d71e12a28502a Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Mon, 2 Dec 2024 15:05:51 +0100 Subject: [PATCH 16/20] [TASK] Removed php unit dependeny as it is part of testing framework --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index b157aac..80ff4b6 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,6 @@ "ergebnis/composer-normalize": "^2.44", "friendsofphp/php-cs-fixer": "^3.14", "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^11.2.5", "roave/security-advisories": "dev-latest", "sbuerk/typo3-cmscomposerinstallers-testingframework-bridge": "^0.1", "typo3/coding-standards": "^0.8", From 145469a07d8d79b7fa08465c1f113ada101fc018 Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Mon, 2 Dec 2024 15:06:22 +0100 Subject: [PATCH 17/20] [TASK] Removed named parameter for integer --- Classes/Command/SynchronizeCropVariantsCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/Command/SynchronizeCropVariantsCommand.php b/Classes/Command/SynchronizeCropVariantsCommand.php index 33da038..959ee86 100644 --- a/Classes/Command/SynchronizeCropVariantsCommand.php +++ b/Classes/Command/SynchronizeCropVariantsCommand.php @@ -137,7 +137,7 @@ protected function getStatementForSysFileReferences(): Result ->where( $queryBuilder->expr()->eq( 'sync_crop_area', - $queryBuilder->createNamedParameter(1) + 1 ) ) ->executeQuery(); From 3ee669193f06d91021b9643433eda296ee59f6c5 Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Mon, 2 Dec 2024 15:08:57 +0100 Subject: [PATCH 18/20] [TASK] Replaced willReturnOnConsecutiveCalls function --- .../SynchronizeCropVariantsCommandTest.php | 58 +++++++++++++------ 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/Tests/Functional/Command/SynchronizeCropVariantsCommandTest.php b/Tests/Functional/Command/SynchronizeCropVariantsCommandTest.php index cc93d8e..b857227 100644 --- a/Tests/Functional/Command/SynchronizeCropVariantsCommandTest.php +++ b/Tests/Functional/Command/SynchronizeCropVariantsCommandTest.php @@ -123,11 +123,16 @@ public function runWithEmptyCropColumnWillSkipRecord(): void $this->outputMock ->expects(self::exactly(3)) ->method('writeln') - ->willReturnOnConsecutiveCalls( - 'Start synchronizing crop variants of table sys_file_reference', - 'SKIP: Column "crop" of sys_file_reference record with UID 1 is empty', - 'We had 1 sys_file_reference records in total. 0 records were processed successfully and 1 records must be skipped because of invalid values', - ); + ->willReturnCallback(function () { + static $calls = 0; + $responses = [ + 'Start synchronizing crop variants of table sys_file_reference', + 'SKIP: Column "crop" of sys_file_reference record with UID 1 is empty', + 'We had 1 sys_file_reference records in total. 0 records were processed successfully and 1 records must be skipped because of invalid values', + ]; + + return $responses[$calls++]; + }); $this->subject->run( $this->inputMock, @@ -159,11 +164,16 @@ public function runWithEmptyPidColumnWillSkipRecord(): void $this->outputMock ->expects(self::exactly(3)) ->method('writeln') - ->willReturnOnConsecutiveCalls( - 'Start synchronizing crop variants of table sys_file_reference', - 'SKIP: Column "pid" of sys_file_reference record with UID 1 is empty', - 'We had 1 sys_file_reference records in total. 0 records were processed successfully and 1 records must be skipped because of invalid values', - ); + ->willReturnCallback(function () { + static $calls = 0; + $responses = [ + 'Start synchronizing crop variants of table sys_file_reference', + 'SKIP: Column "pid" of sys_file_reference record with UID 1 is empty', + 'We had 1 sys_file_reference records in total. 0 records were processed successfully and 1 records must be skipped because of invalid values', + ]; + + return $responses[$calls++]; + }); $this->subject->run( $this->inputMock, @@ -197,11 +207,16 @@ public function runWithUnchangedCropWillSkipRecord(): void $this->outputMock ->expects(self::exactly(3)) ->method('writeln') - ->willReturnOnConsecutiveCalls( - 'Start synchronizing crop variants of table sys_file_reference', - 'SKIP: Column "crop" of table "sys_file_reference" with UID 1 because it is unchanged, empty or invalid JSON', - 'We had 1 sys_file_reference records in total. 0 records were processed successfully and 1 records must be skipped because of invalid values', - ); + ->willReturnCallback(function () { + static $calls = 0; + $responses = [ + 'Start synchronizing crop variants of table sys_file_reference', + 'SKIP: Column "crop" of table "sys_file_reference" with UID 1 because it is unchanged, empty or invalid JSON', + 'We had 1 sys_file_reference records in total. 0 records were processed successfully and 1 records must be skipped because of invalid values', + ]; + + return $responses[$calls++]; + }); $this->updateCropVariantsServiceMock ->expects(self::atLeastOnce()) @@ -225,10 +240,15 @@ public function runWithChangedCropWillUpdateRecord(): void $this->outputMock ->expects(self::exactly(2)) ->method('writeln') - ->willReturnOnConsecutiveCalls( - 'Start synchronizing crop variants of table sys_file_reference', - 'We had 3 sys_file_reference records in total. 3 records were processed successfully and 0 records must be skipped because of invalid values', - ); + ->willReturnCallback(function () { + static $calls = 0; + $responses = [ + 'Start synchronizing crop variants of table sys_file_reference', + 'We had 3 sys_file_reference records in total. 3 records were processed successfully and 0 records must be skipped because of invalid values', + ]; + + return $responses[$calls++]; + }); $this->updateCropVariantsServiceMock ->expects(self::atLeastOnce()) From 505091d45ede4a3c44ce9a9a32379f75510adb4b Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Mon, 2 Dec 2024 15:17:40 +0100 Subject: [PATCH 19/20] [TASK] Removed typo3 12 compatibilites --- Build/phpunit/UnitTestsBootstrap.php | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/Build/phpunit/UnitTestsBootstrap.php b/Build/phpunit/UnitTestsBootstrap.php index 6266dcb..0a7272f 100644 --- a/Build/phpunit/UnitTestsBootstrap.php +++ b/Build/phpunit/UnitTestsBootstrap.php @@ -56,15 +56,7 @@ // 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); - } + SystemEnvironmentBuilder::run(0, \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::REQUESTTYPE_CLI, $composerMode); $testbase->createDirectory(Environment::getPublicPath() . '/typo3conf/ext'); $testbase->createDirectory(Environment::getPublicPath() . '/typo3temp/assets'); From 39ab473a99437223853de906d1803a563b76dabd Mon Sep 17 00:00:00 2001 From: Hoja Mustaffa Abdul Latheef Date: Mon, 2 Dec 2024 15:46:51 +0100 Subject: [PATCH 20/20] [TASK] Fixed prepared statement usage in query in command controller --- Classes/Command/SynchronizeCropVariantsCommand.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Classes/Command/SynchronizeCropVariantsCommand.php b/Classes/Command/SynchronizeCropVariantsCommand.php index 959ee86..78a6112 100644 --- a/Classes/Command/SynchronizeCropVariantsCommand.php +++ b/Classes/Command/SynchronizeCropVariantsCommand.php @@ -17,6 +17,7 @@ use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -137,7 +138,7 @@ protected function getStatementForSysFileReferences(): Result ->where( $queryBuilder->expr()->eq( 'sync_crop_area', - 1 + $queryBuilder->createNamedParameter(1, Connection::PARAM_STR) ) ) ->executeQuery();