diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bd1a2ab7..7985d9c0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ on: jobs: docker-compose: name: docker-compose (production container) - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: checkout uses: actions/checkout@v3 @@ -22,9 +22,9 @@ jobs: run: curl --insecure https://localhost/openapi -vvv - name: docker stop run: docker-compose -f docker-compose.ci.yml stop - php80: - name: PHP 8.0 - runs-on: ubuntu-20.04 + php81: + name: PHP 8.1 + runs-on: ubuntu-22.04 services: postgres: image: postgres:14 @@ -40,7 +40,7 @@ jobs: run: | while ! nc -z localhost 5432; do sleep 0.1; done - name: composer test - uses: docker://chubbyphp/ci-php80:latest + uses: docker://chubbyphp/ci-php81:latest env: APP_ENV: phpunit DATABASE_USER: root @@ -50,9 +50,9 @@ jobs: DATABASE_PORT: 5432 COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} STRYKER_DASHBOARD_API_KEY: ${{ secrets.STRYKER_DASHBOARD_API_KEY }} - php81: - name: PHP 8.1 - runs-on: ubuntu-20.04 + php82: + name: PHP 8.2 + runs-on: ubuntu-22.04 services: postgres: image: postgres:14 @@ -68,7 +68,7 @@ jobs: run: | while ! nc -z localhost 5432; do sleep 0.1; done - name: composer test - uses: docker://chubbyphp/ci-php81:latest + uses: docker://chubbyphp/ci-php82:latest env: APP_ENV: phpunit DATABASE_USER: root @@ -78,9 +78,9 @@ jobs: DATABASE_PORT: 5432 COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} STRYKER_DASHBOARD_API_KEY: ${{ secrets.STRYKER_DASHBOARD_API_KEY }} - php82: - name: PHP 8.2 - runs-on: ubuntu-20.04 + php83: + name: PHP 8.3 + runs-on: ubuntu-22.04 services: postgres: image: postgres:14 @@ -96,7 +96,7 @@ jobs: run: | while ! nc -z localhost 5432; do sleep 0.1; done - name: composer test - uses: docker://chubbyphp/ci-php82:latest + uses: docker://chubbyphp/ci-php83:latest env: APP_ENV: phpunit DATABASE_USER: root diff --git a/.gitignore b/.gitignore index 39e3aba4..be263079 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,9 @@ -build +.DS_Store +.idea/ +.phpunit.cache +.vscode/ +build/ composer.lock database -var -vendor +var/ +vendor/ diff --git a/README.md b/README.md index 64cca6fd..5de98bdd 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![CI](https://github.com/chubbyphp/petstore/workflows/CI/badge.svg?branch=chubbyphp)](https://github.com/chubbyphp/petstore/actions?query=workflow%3ACI) [![Coverage Status](https://coveralls.io/repos/github/chubbyphp/petstore/badge.svg?branch=chubbyphp)](https://coveralls.io/github/chubbyphp/petstore?branch=chubbyphp) -[![Infection MSI](https://badge.stryker-mutator.io/github.com/chubbyphp/petstore/chubbyphp)](https://dashboard.stryker-mutator.io/reports/github.com/chubbyphp/petstore/chubbyphp) +[![Mutation testing badge](https://img.shields.io/endpoint?style=flat&url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fchubbyphp%2Fpetstore%2Fchubbyphp)](https://dashboard.stryker-mutator.io/reports/github.com/chubbyphp/petstore/chubbyphp) ## Description @@ -10,26 +10,26 @@ A simple skeleton to build api's based on the [chubbyphp-framework][1]. ## Requirements - * php: ^8.0 - * [chubbyphp/chubbyphp-api-http][2]: ^5.0.1 - * [chubbyphp/chubbyphp-clean-directories][3]: ^1.2 - * [chubbyphp/chubbyphp-cors][4]: ^1.4 - * [chubbyphp/chubbyphp-decode-encode][5]: ^1.0.1 - * [chubbyphp/chubbyphp-deserialization][6]: ^3.5.2 - * [chubbyphp/chubbyphp-framework][7]: ^5.0.3 - * [chubbyphp/chubbyphp-framework-router-fastroute][8]: ^2.0.1 - * [chubbyphp/chubbyphp-http-exception][9]: ^1.0.1 - * [chubbyphp/chubbyphp-laminas-config][10]: ^1.3 - * [chubbyphp/chubbyphp-laminas-config-doctrine][11]: ^2.0.3 - * [chubbyphp/chubbyphp-laminas-config-factory][12]: ^1.2 - * [chubbyphp/chubbyphp-negotiation][13]: ^1.9 - * [chubbyphp/chubbyphp-serialization][14]: ^3.3.1 - * [chubbyphp/chubbyphp-validation][15]: ^3.12.4 - * [doctrine/orm][16]: ^2.14 - * [monolog/monolog][17]: ^2.8 - * [ramsey/uuid][18]: ^4.7 - * [slim/psr7][19]: ^1.6 - * [symfony/console][20]: ^6.0.17 + * php: ^8.1 + * [chubbyphp/chubbyphp-api-http][2]: ^6.0 + * [chubbyphp/chubbyphp-clean-directories][3]: ^1.3.1 + * [chubbyphp/chubbyphp-cors][4]: ^1.5 + * [chubbyphp/chubbyphp-decode-encode][5]: ^1.1 + * [chubbyphp/chubbyphp-deserialization][6]: ^4.1 + * [chubbyphp/chubbyphp-framework][7]: ^5.1.1 + * [chubbyphp/chubbyphp-framework-router-fastroute][8]: ^2.1 + * [chubbyphp/chubbyphp-http-exception][9]: ^1.1 + * [chubbyphp/chubbyphp-laminas-config][10]: ^1.4 + * [chubbyphp/chubbyphp-laminas-config-doctrine][11]: ^2.2 + * [chubbyphp/chubbyphp-laminas-config-factory][12]: ^1.3 + * [chubbyphp/chubbyphp-negotiation][13]: ^2.0 + * [chubbyphp/chubbyphp-serialization][14]: ^4.0 + * [chubbyphp/chubbyphp-validation][15]: ^4.0 + * [doctrine/orm][16]: ^2.17.2 + * [monolog/monolog][17]: ^3.5 + * [ramsey/uuid][18]: ^4.7.5 + * [slim/psr7][19]: ^1.6.1 + * [symfony/console][20]: ^6.4.2 ## Environment diff --git a/composer.json b/composer.json index 8c9d99dc..4b03f7f8 100644 --- a/composer.json +++ b/composer.json @@ -14,36 +14,35 @@ } ], "require": { - "php": "^8.0", - "chubbyphp/chubbyphp-api-http": "^5.0.1", - "chubbyphp/chubbyphp-clean-directories": "^1.2", - "chubbyphp/chubbyphp-cors": "^1.4", - "chubbyphp/chubbyphp-decode-encode": "^1.0.1", - "chubbyphp/chubbyphp-deserialization": "^3.5.2", - "chubbyphp/chubbyphp-framework": "^5.0.3", - "chubbyphp/chubbyphp-framework-router-fastroute": "^2.0.1", - "chubbyphp/chubbyphp-http-exception": "^1.0.1", - "chubbyphp/chubbyphp-laminas-config": "^1.3", - "chubbyphp/chubbyphp-laminas-config-doctrine": "^2.0.3", - "chubbyphp/chubbyphp-laminas-config-factory": "^1.2", - "chubbyphp/chubbyphp-negotiation": "^1.9", - "chubbyphp/chubbyphp-serialization": "^3.3.1", - "chubbyphp/chubbyphp-validation": "^3.12.4", - "doctrine/orm": "^2.14", - "monolog/monolog": "^2.8", - "ramsey/uuid": "^4.7", - "slim/psr7": "^1.6", - "symfony/console": "^6.0.17" + "php": "^8.1", + "chubbyphp/chubbyphp-api-http": "^6.0", + "chubbyphp/chubbyphp-clean-directories": "^1.3.1", + "chubbyphp/chubbyphp-cors": "^1.5", + "chubbyphp/chubbyphp-decode-encode": "^1.1", + "chubbyphp/chubbyphp-deserialization": "^4.1", + "chubbyphp/chubbyphp-framework": "^5.1.1", + "chubbyphp/chubbyphp-framework-router-fastroute": "^2.1", + "chubbyphp/chubbyphp-http-exception": "^1.1", + "chubbyphp/chubbyphp-laminas-config": "^1.4", + "chubbyphp/chubbyphp-laminas-config-doctrine": "^2.1", + "chubbyphp/chubbyphp-laminas-config-factory": "^1.3", + "chubbyphp/chubbyphp-negotiation": "^2.0", + "chubbyphp/chubbyphp-serialization": "^4.0", + "chubbyphp/chubbyphp-validation": "^4.0", + "doctrine/orm": "^2.17.2", + "monolog/monolog": "^3.5", + "ramsey/uuid": "^4.7.5", + "slim/psr7": "^1.6.1", + "symfony/console": "^6.4.2" }, "require-dev": { "chubbyphp/chubbyphp-dev-helper": "dev-master", - "chubbyphp/chubbyphp-mock": "^1.6.2", - "infection/infection": "^0.26.16", - "php-coveralls/php-coveralls": "^2.5.3", - "phploc/phploc": "^7.0.2", - "phpstan/extension-installer": "^1.2", - "phpstan/phpstan": "^1.9.4", - "phpunit/phpunit": "^9.5.27" + "chubbyphp/chubbyphp-mock": "^1.7", + "infection/infection": "^0.27.9", + "php-coveralls/php-coveralls": "^2.7", + "phpstan/extension-installer": "^1.3.1", + "phpstan/phpstan": "^1.10.50", + "phpunit/phpunit": "^10.5.5" }, "autoload": { "psr-4": { @@ -89,7 +88,6 @@ "@test:infection", "@test:integration", "@test:static-analysis", - "@test:loc", "@test:cs" ], "test:cs": "mkdir -p build && PHP_CS_FIXER_IGNORE_ENV=1 vendor/bin/php-cs-fixer fix --dry-run --stop-on-violation --cache-file=build/phpcs.cache", @@ -97,7 +95,6 @@ "test:integration": "vendor/bin/phpunit --configuration phpunit.integration.xml --cache-result-file=build/phpunit/result.integration.cache", "test:lint": "mkdir -p build && find src tests -name '*.php' -print0 | xargs -0 -n1 -P$(nproc) php -l | tee build/phplint.log", "test:static-analysis": "mkdir -p build && bash -c 'vendor/bin/phpstan analyse src --no-progress --level=8 --error-format=junit | tee build/phpstan.junit.xml; if [ ${PIPESTATUS[0]} -ne \"0\" ]; then exit 1; fi'", - "test:loc": "mkdir -p build && vendor/bin/phploc src | tee build/phploc.log", "test:unit": "vendor/bin/phpunit --coverage-text --coverage-clover=build/phpunit/clover.xml --coverage-html=build/phpunit/coverage-html --coverage-xml=build/phpunit/coverage-xml --log-junit=build/phpunit/junit.xml --cache-result-file=build/phpunit/result.cache" } } diff --git a/config/dev.php b/config/dev.php index 4a2dedfc..aff2a259 100644 --- a/config/dev.php +++ b/config/dev.php @@ -3,15 +3,14 @@ declare(strict_types=1); use Chubbyphp\Cors\Negotiation\Origin\AllowOriginRegex; -use Chubbyphp\Laminas\Config\Doctrine\ServiceFactory\Common\Cache\ArrayCacheFactory; -use Monolog\Logger; +use Monolog\Level; $config = require __DIR__.'/prod.php'; $config['chubbyphp']['cors']['allowOrigins']['^https?\:\/\/(localhost|127\.\d+.\d+.\d+)(\:\d+)?$'] = AllowOriginRegex::class; $config['debug'] = true; -$config['dependencies']['factories'][Cache::class] = ArrayCacheFactory::class; +$config['doctrine']['cache'] = ['array' => []]; $config['fastroute']['cache'] = null; -$config['monolog']['level'] = Logger::DEBUG; +$config['monolog']['level'] = Level::Notice; return $config; diff --git a/config/prod.php b/config/prod.php index 6c9c0a43..86167338 100644 --- a/config/prod.php +++ b/config/prod.php @@ -82,12 +82,12 @@ use Chubbyphp\Validation\ServiceFactory\ValidationMappingProviderRegistryFactory; use Chubbyphp\Validation\ServiceFactory\ValidatorFactory; use Chubbyphp\Validation\ValidatorInterface; -use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver; use Doctrine\DBAL\Tools\Console\ConnectionProvider; use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Tools\Console\EntityManagerProvider; -use Monolog\Logger; +use Doctrine\Persistence\Mapping\Driver\MappingDriver; +use Monolog\Level; use Psr\Http\Message\ResponseFactoryInterface; use Psr\Http\Message\StreamFactoryInterface; use Psr\Http\Server\MiddlewareInterface; @@ -206,6 +206,6 @@ 'monolog' => [ 'name' => 'petstore', 'path' => $logDir . '/' . $env . '.log', - 'level' => Logger::NOTICE, + 'level' => Level::Notice, ], ]; diff --git a/docker-compose.yml b/docker-compose.yml index a6c5affc..750e9e33 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -30,6 +30,8 @@ services: - postgres extra_hosts: - "host.docker.internal:host-gateway" + ports: + - '9003:9003' postgres: container_name: petstore-postgres hostname: petstore-postgres diff --git a/docker/development/php/Dockerfile b/docker/development/php/Dockerfile index c8495764..958ce675 100644 --- a/docker/development/php/Dockerfile +++ b/docker/development/php/Dockerfile @@ -1,10 +1,10 @@ -FROM rockylinux:9.1 +FROM rockylinux:9.3 SHELL ["/bin/bash", "-c"] RUN dnf upgrade -y --refresh -RUN dnf install -y epel-release https://rpms.remirepo.net/enterprise/remi-release-9.1.rpm +RUN dnf install -y epel-release https://rpms.remirepo.net/enterprise/remi-release-9.rpm RUN dnf install -y --nobest \ compat-openssl11 \ @@ -12,19 +12,19 @@ RUN dnf install -y --nobest \ glibc-langpack-de \ langpacks-de \ nmap-ncat \ - php82-php-ast \ - php82-php-cli \ - php82-php-devel \ - php82-php-fpm \ - php82-php-intl \ - php82-php-mbstring \ - php82-php-opcache \ - php82-php-pecl-apcu \ - php82-php-pecl-pcov \ - php82-php-pecl-xdebug3 \ - php82-php-pecl-zip \ - php82-php-pgsql \ - php82-php-xml \ + php83-php-ast \ + php83-php-cli \ + php83-php-devel \ + php83-php-fpm \ + php83-php-intl \ + php83-php-mbstring \ + php83-php-opcache \ + php83-php-pecl-apcu \ + php83-php-pecl-pcov \ + php83-php-pecl-xdebug3 \ + php83-php-pecl-zip \ + php83-php-pgsql \ + php83-php-xml \ procps-ng \ sudo \ supervisor \ @@ -32,9 +32,9 @@ RUN dnf install -y --nobest \ vim \ zsh -RUN ln -sf /usr/bin/php82 /usr/bin/php \ - && rm /etc/opt/remi/php82/php.d/15-xdebug.ini \ - && rm /etc/opt/remi/php82/php.d/40-pcov.ini +RUN ln -sf /usr/bin/php83 /usr/bin/php \ + && rm /etc/opt/remi/php83/php.d/15-xdebug.ini \ + && rm /etc/opt/remi/php83/php.d/40-pcov.ini ENV TZ=Europe/Zurich diff --git a/docker/development/php/files/etc/opt/remi/php82/php.d/99-development.ini b/docker/development/php/files/etc/opt/remi/php83/php.d/99-development.ini similarity index 100% rename from docker/development/php/files/etc/opt/remi/php82/php.d/99-development.ini rename to docker/development/php/files/etc/opt/remi/php83/php.d/99-development.ini diff --git a/docker/development/php/files/etc/supervisord.conf b/docker/development/php/files/etc/supervisord.conf index 6d83c121..d09f82af 100644 --- a/docker/development/php/files/etc/supervisord.conf +++ b/docker/development/php/files/etc/supervisord.conf @@ -15,7 +15,7 @@ supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface serverurl=unix:///tmp/supervisor.sock [program:php-fpm] -command=/opt/remi/php82/root/usr/sbin/php-fpm -c /etc/opt/remi/php82/php-fpm.conf -F +command=/opt/remi/php83/root/usr/sbin/php-fpm -c /etc/opt/remi/php83/php-fpm.conf -F stdout_logfile=/tmp/supervisord.log stdout_syslog=true stderr_logfile=/tmp/supervisord.log diff --git a/docker/development/php/files/home/php/.sharedrc b/docker/development/php/files/home/php/.sharedrc index 343f06e6..22519149 100644 --- a/docker/development/php/files/home/php/.sharedrc +++ b/docker/development/php/files/home/php/.sharedrc @@ -15,7 +15,7 @@ alias rm='rm -i' alias php-fpm-restart='/usr/bin/supervisorctl -c /etc/supervisord.conf restart php-fpm' -alias xdebug-on='echo "zend_extension=xdebug.so" | sudo tee /etc/opt/remi/php82/php.d/15-xdebug.ini && php-fpm-restart' -alias xdebug-off='sudo rm /etc/opt/remi/php82/php.d/15-xdebug.ini && php-fpm-restart' -alias pcov-on='echo "extension=pcov.so" | sudo tee /etc/opt/remi/php82/php.d/40-pcov.ini && php-fpm-restart' -alias pcov-off='sudo rm /etc/opt/remi/php82/php.d/40-pcov.ini && php-fpm-restart' +alias xdebug-on='echo "zend_extension=xdebug.so" | sudo tee /etc/opt/remi/php83/php.d/15-xdebug.ini && php-fpm-restart' +alias xdebug-off='sudo rm /etc/opt/remi/php83/php.d/15-xdebug.ini && php-fpm-restart' +alias pcov-on='echo "extension=pcov.so" | sudo tee /etc/opt/remi/php83/php.d/40-pcov.ini && php-fpm-restart' +alias pcov-off='sudo rm /etc/opt/remi/php83/php.d/40-pcov.ini && php-fpm-restart' diff --git a/docker/production/php/Dockerfile b/docker/production/php/Dockerfile index 5a19a386..ced64b82 100644 --- a/docker/production/php/Dockerfile +++ b/docker/production/php/Dockerfile @@ -1,10 +1,10 @@ -FROM rockylinux:9.1 +FROM rockylinux:9.3 SHELL ["/bin/bash", "-c"] RUN dnf upgrade -y --refresh -RUN dnf install -y epel-release https://rpms.remirepo.net/enterprise/remi-release-9.1.rpm +RUN dnf install -y epel-release https://rpms.remirepo.net/enterprise/remi-release-9.rpm RUN dnf install -y --nobest \ compat-openssl11 \ @@ -12,19 +12,19 @@ RUN dnf install -y --nobest \ glibc-langpack-de \ langpacks-de \ nmap-ncat \ - php82-php-ast \ - php82-php-cli \ - php82-php-devel \ - php82-php-fpm \ - php82-php-intl \ - php82-php-mbstring \ - php82-php-opcache \ - php82-php-pecl-apcu \ - php82-php-pecl-pcov \ - php82-php-pecl-xdebug3 \ - php82-php-pecl-zip \ - php82-php-pgsql \ - php82-php-xml \ + php83-php-ast \ + php83-php-cli \ + php83-php-devel \ + php83-php-fpm \ + php83-php-intl \ + php83-php-mbstring \ + php83-php-opcache \ + php83-php-pecl-apcu \ + php83-php-pecl-pcov \ + php83-php-pecl-xdebug3 \ + php83-php-pecl-zip \ + php83-php-pgsql \ + php83-php-xml \ procps-ng \ sudo \ supervisor \ @@ -32,8 +32,8 @@ RUN dnf install -y --nobest \ vim \ zsh -RUN ln -sf /usr/bin/php82 /usr/bin/php \ - && echo "extension=pcov.so" > /etc/opt/remi/php82/php.d/40-pcov.ini +RUN ln -sf /usr/bin/php83 /usr/bin/php \ + && echo "extension=pcov.so" > /etc/opt/remi/php83/php.d/40-pcov.ini ENV TZ=Europe/Zurich @@ -63,4 +63,4 @@ WORKDIR /app RUN composer install --no-dev --optimize-autoloader -CMD /opt/remi/php82/root/usr/sbin/php-fpm -c /etc/opt/remi/php82/php-fpm.conf -F +CMD /opt/remi/php83/root/usr/sbin/php-fpm -c /etc/opt/remi/php83/php-fpm.conf -F diff --git a/docker/production/php/files/etc/opt/remi/php82/php-fpm.conf b/docker/production/php/files/etc/opt/remi/php83/php-fpm.conf similarity index 100% rename from docker/production/php/files/etc/opt/remi/php82/php-fpm.conf rename to docker/production/php/files/etc/opt/remi/php83/php-fpm.conf diff --git a/docker/production/php/files/etc/opt/remi/php82/php.ini b/docker/production/php/files/etc/opt/remi/php83/php.ini similarity index 100% rename from docker/production/php/files/etc/opt/remi/php82/php.ini rename to docker/production/php/files/etc/opt/remi/php83/php.ini diff --git a/openapi.yml b/openapi.yml index c46db028..4d9eeec8 100644 --- a/openapi.yml +++ b/openapi.yml @@ -54,7 +54,6 @@ paths: required: false schema: type: string - example: Cherry - name: sort[name] in: query description: Sort by name diff --git a/phpunit.integration.xml b/phpunit.integration.xml index 71d8edde..c06f3f4f 100644 --- a/phpunit.integration.xml +++ b/phpunit.integration.xml @@ -1,11 +1,12 @@ - + ./tests/Integration - + + diff --git a/phpunit.xml b/phpunit.xml index ff305773..c8265dbe 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,28 +1,18 @@ - - - - ./src - - - ./src/console.php - ./src/container.php - ./src/web.php - - - - - ./tests/Unit - - + + + + ./tests/Unit + + + + + ./src + + + ./src/console.php + ./src/container.php + ./src/web.php + + diff --git a/src/Collection/PetCollection.php b/src/Collection/PetCollection.php index 8f9b9a6a..d22ac426 100644 --- a/src/Collection/PetCollection.php +++ b/src/Collection/PetCollection.php @@ -4,6 +4,4 @@ namespace App\Collection; -final class PetCollection extends AbstractCollection -{ -} +final class PetCollection extends AbstractCollection {} diff --git a/src/Mapping/Deserialization/PetCollectionMapping.php b/src/Mapping/Deserialization/PetCollectionMapping.php index ad878db9..9e99734d 100644 --- a/src/Mapping/Deserialization/PetCollectionMapping.php +++ b/src/Mapping/Deserialization/PetCollectionMapping.php @@ -6,12 +6,14 @@ use App\Collection\PetCollection; use Chubbyphp\Deserialization\Denormalizer\ConvertTypeFieldDenormalizer; -use Chubbyphp\Deserialization\Mapping\DenormalizationFieldMappingBuilder; +use Chubbyphp\Deserialization\Mapping\DenormalizationFieldMappingFactoryInterface; use Chubbyphp\Deserialization\Mapping\DenormalizationFieldMappingInterface; use Chubbyphp\Deserialization\Mapping\DenormalizationObjectMappingInterface; final class PetCollectionMapping implements DenormalizationObjectMappingInterface { + public function __construct(private DenormalizationFieldMappingFactoryInterface $denormalizationFieldMappingFactory) {} + public function getClass(): string { return PetCollection::class; @@ -32,12 +34,10 @@ public function getDenormalizationFactory(string $path, ?string $type = null): c public function getDenormalizationFieldMappings(string $path, ?string $type = null): array { return [ - DenormalizationFieldMappingBuilder::createConvertType('offset', ConvertTypeFieldDenormalizer::TYPE_INT) - ->getMapping(), - DenormalizationFieldMappingBuilder::createConvertType('limit', ConvertTypeFieldDenormalizer::TYPE_INT) - ->getMapping(), - DenormalizationFieldMappingBuilder::create('filters')->getMapping(), - DenormalizationFieldMappingBuilder::create('sort')->getMapping(), + $this->denormalizationFieldMappingFactory->createConvertType('offset', ConvertTypeFieldDenormalizer::TYPE_INT), + $this->denormalizationFieldMappingFactory->createConvertType('limit', ConvertTypeFieldDenormalizer::TYPE_INT), + $this->denormalizationFieldMappingFactory->create('filters'), + $this->denormalizationFieldMappingFactory->create('sort'), ]; } } diff --git a/src/Mapping/Deserialization/PetMapping.php b/src/Mapping/Deserialization/PetMapping.php index 36b60863..a243a109 100644 --- a/src/Mapping/Deserialization/PetMapping.php +++ b/src/Mapping/Deserialization/PetMapping.php @@ -9,12 +9,14 @@ use Chubbyphp\Deserialization\Accessor\MethodAccessor; use Chubbyphp\Deserialization\Denormalizer\ConvertTypeFieldDenormalizer; use Chubbyphp\Deserialization\Denormalizer\Relation\EmbedManyFieldDenormalizer; -use Chubbyphp\Deserialization\Mapping\DenormalizationFieldMappingBuilder; +use Chubbyphp\Deserialization\Mapping\DenormalizationFieldMappingFactoryInterface; use Chubbyphp\Deserialization\Mapping\DenormalizationFieldMappingInterface; use Chubbyphp\Deserialization\Mapping\DenormalizationObjectMappingInterface; final class PetMapping implements DenormalizationObjectMappingInterface { + public function __construct(private DenormalizationFieldMappingFactoryInterface $denormalizationFieldMappingFactory) {} + public function getClass(): string { return Pet::class; @@ -35,15 +37,13 @@ public function getDenormalizationFactory(string $path, ?string $type = null): c public function getDenormalizationFieldMappings(string $path, ?string $type = null): array { return [ - DenormalizationFieldMappingBuilder::createConvertType('name', ConvertTypeFieldDenormalizer::TYPE_STRING) - ->getMapping(), - DenormalizationFieldMappingBuilder::createConvertType('tag', ConvertTypeFieldDenormalizer::TYPE_STRING) - ->getMapping(), - DenormalizationFieldMappingBuilder::create( + $this->denormalizationFieldMappingFactory->createConvertType('name', ConvertTypeFieldDenormalizer::TYPE_STRING), + $this->denormalizationFieldMappingFactory->createConvertType('tag', ConvertTypeFieldDenormalizer::TYPE_STRING), + $this->denormalizationFieldMappingFactory->create( 'vaccinations', false, new EmbedManyFieldDenormalizer(Vaccination::class, new MethodAccessor('vaccinations')) - )->getMapping(), + ), ]; } } diff --git a/src/Mapping/Deserialization/VaccinationMapping.php b/src/Mapping/Deserialization/VaccinationMapping.php index 514adff7..3b87cd1b 100644 --- a/src/Mapping/Deserialization/VaccinationMapping.php +++ b/src/Mapping/Deserialization/VaccinationMapping.php @@ -6,12 +6,14 @@ use App\Model\Vaccination; use Chubbyphp\Deserialization\Denormalizer\ConvertTypeFieldDenormalizer; -use Chubbyphp\Deserialization\Mapping\DenormalizationFieldMappingBuilder; +use Chubbyphp\Deserialization\Mapping\DenormalizationFieldMappingFactoryInterface; use Chubbyphp\Deserialization\Mapping\DenormalizationFieldMappingInterface; use Chubbyphp\Deserialization\Mapping\DenormalizationObjectMappingInterface; final class VaccinationMapping implements DenormalizationObjectMappingInterface { + public function __construct(private DenormalizationFieldMappingFactoryInterface $denormalizationFieldMappingFactory) {} + public function getClass(): string { return Vaccination::class; @@ -32,8 +34,7 @@ public function getDenormalizationFactory(string $path, ?string $type = null): c public function getDenormalizationFieldMappings(string $path, ?string $type = null): array { return [ - DenormalizationFieldMappingBuilder::createConvertType('name', ConvertTypeFieldDenormalizer::TYPE_STRING) - ->getMapping(), + $this->denormalizationFieldMappingFactory->createConvertType('name', ConvertTypeFieldDenormalizer::TYPE_STRING), ]; } } diff --git a/src/Mapping/Serialization/AbstractCollectionMapping.php b/src/Mapping/Serialization/AbstractCollectionMapping.php index 04ba2a79..643ab5b8 100644 --- a/src/Mapping/Serialization/AbstractCollectionMapping.php +++ b/src/Mapping/Serialization/AbstractCollectionMapping.php @@ -16,9 +16,7 @@ abstract class AbstractCollectionMapping implements NormalizationObjectMappingInterface { - public function __construct(protected UrlGeneratorInterface $urlGenerator) - { - } + public function __construct(protected UrlGeneratorInterface $urlGenerator) {} /** * @return array diff --git a/src/Mapping/Serialization/AbstractModelMapping.php b/src/Mapping/Serialization/AbstractModelMapping.php index e6c2b2da..ab21effb 100644 --- a/src/Mapping/Serialization/AbstractModelMapping.php +++ b/src/Mapping/Serialization/AbstractModelMapping.php @@ -15,9 +15,7 @@ abstract class AbstractModelMapping implements NormalizationObjectMappingInterface { - public function __construct(protected UrlGeneratorInterface $urlGenerator) - { - } + public function __construct(protected UrlGeneratorInterface $urlGenerator) {} /** * @return array diff --git a/src/Repository/PetRepository.php b/src/Repository/PetRepository.php index e36ab6ee..7df48417 100644 --- a/src/Repository/PetRepository.php +++ b/src/Repository/PetRepository.php @@ -13,9 +13,7 @@ final class PetRepository implements RepositoryInterface { - public function __construct(private EntityManager $entityManager) - { - } + public function __construct(private EntityManager $entityManager) {} /** * @param CollectionInterface|PetCollection $petCollection diff --git a/src/RequestHandler/Api/Crud/CreateRequestHandler.php b/src/RequestHandler/Api/Crud/CreateRequestHandler.php index f48821f2..820d7453 100644 --- a/src/RequestHandler/Api/Crud/CreateRequestHandler.php +++ b/src/RequestHandler/Api/Crud/CreateRequestHandler.php @@ -28,8 +28,7 @@ public function __construct( private RequestManagerInterface $requestManager, private ResponseManagerInterface $responseManager, private ValidatorInterface $validator - ) { - } + ) {} public function handle(ServerRequestInterface $request): ResponseInterface { diff --git a/src/RequestHandler/Api/Crud/DeleteRequestHandler.php b/src/RequestHandler/Api/Crud/DeleteRequestHandler.php index dd6ac4a8..d370e51d 100644 --- a/src/RequestHandler/Api/Crud/DeleteRequestHandler.php +++ b/src/RequestHandler/Api/Crud/DeleteRequestHandler.php @@ -17,8 +17,7 @@ final class DeleteRequestHandler implements RequestHandlerInterface public function __construct( private RepositoryInterface $repository, private ResponseManagerInterface $responseManager - ) { - } + ) {} public function handle(ServerRequestInterface $request): ResponseInterface { diff --git a/src/RequestHandler/Api/Crud/ListRequestHandler.php b/src/RequestHandler/Api/Crud/ListRequestHandler.php index 59ccf248..66ac1367 100644 --- a/src/RequestHandler/Api/Crud/ListRequestHandler.php +++ b/src/RequestHandler/Api/Crud/ListRequestHandler.php @@ -25,8 +25,7 @@ public function __construct( private RequestManagerInterface $requestManager, private ResponseManagerInterface $responseManager, private ValidatorInterface $validator - ) { - } + ) {} public function handle(ServerRequestInterface $request): ResponseInterface { diff --git a/src/RequestHandler/Api/Crud/ReadRequestHandler.php b/src/RequestHandler/Api/Crud/ReadRequestHandler.php index 5bf04f24..3c4cc671 100644 --- a/src/RequestHandler/Api/Crud/ReadRequestHandler.php +++ b/src/RequestHandler/Api/Crud/ReadRequestHandler.php @@ -19,8 +19,7 @@ final class ReadRequestHandler implements RequestHandlerInterface public function __construct( private RepositoryInterface $repository, private ResponseManagerInterface $responseManager - ) { - } + ) {} public function handle(ServerRequestInterface $request): ResponseInterface { diff --git a/src/RequestHandler/Api/Crud/UpdateRequestHandler.php b/src/RequestHandler/Api/Crud/UpdateRequestHandler.php index 4903a4fe..6690580f 100644 --- a/src/RequestHandler/Api/Crud/UpdateRequestHandler.php +++ b/src/RequestHandler/Api/Crud/UpdateRequestHandler.php @@ -27,8 +27,7 @@ public function __construct( private RequestManagerInterface $requestManager, private ResponseManagerInterface $responseManager, private ValidatorInterface $validator - ) { - } + ) {} public function handle(ServerRequestInterface $request): ResponseInterface { diff --git a/src/RequestHandler/OpenapiRequestHandler.php b/src/RequestHandler/OpenapiRequestHandler.php index f2ffc886..e6191965 100644 --- a/src/RequestHandler/OpenapiRequestHandler.php +++ b/src/RequestHandler/OpenapiRequestHandler.php @@ -15,8 +15,7 @@ final class OpenapiRequestHandler implements RequestHandlerInterface public function __construct( private ResponseFactoryInterface $responseFactory, private StreamFactoryInterface $streamFactory - ) { - } + ) {} public function handle(ServerRequestInterface $request): ResponseInterface { diff --git a/src/RequestHandler/PingRequestHandler.php b/src/RequestHandler/PingRequestHandler.php index ddcdd6e8..72e905e1 100644 --- a/src/RequestHandler/PingRequestHandler.php +++ b/src/RequestHandler/PingRequestHandler.php @@ -13,8 +13,7 @@ final class PingRequestHandler implements RequestHandlerInterface { public function __construct( private ResponseFactoryInterface $responseFactory, - ) { - } + ) {} public function handle(ServerRequestInterface $request): ResponseInterface { diff --git a/src/ServiceFactory/Deserialization/DenormalizationObjectMappingsFactory.php b/src/ServiceFactory/Deserialization/DenormalizationObjectMappingsFactory.php index b7dcd1f4..8952d99c 100644 --- a/src/ServiceFactory/Deserialization/DenormalizationObjectMappingsFactory.php +++ b/src/ServiceFactory/Deserialization/DenormalizationObjectMappingsFactory.php @@ -7,19 +7,26 @@ use App\Mapping\Deserialization\PetCollectionMapping; use App\Mapping\Deserialization\PetMapping; use App\Mapping\Deserialization\VaccinationMapping; +use Chubbyphp\Deserialization\Mapping\DenormalizationFieldMappingFactoryInterface; use Chubbyphp\Deserialization\Mapping\DenormalizationObjectMappingInterface; +use Chubbyphp\Deserialization\ServiceFactory\DenormalizationFieldMappingFactoryFactory; +use Chubbyphp\Laminas\Config\Factory\AbstractFactory; +use Psr\Container\ContainerInterface; -final class DenormalizationObjectMappingsFactory +final class DenormalizationObjectMappingsFactory extends AbstractFactory { /** * @return array */ - public function __invoke(): array + public function __invoke(ContainerInterface $container): array { + /** @var DenormalizationFieldMappingFactoryInterface $denormalizationFieldMappingFactory */ + $denormalizationFieldMappingFactory = $this->resolveDependency($container, DenormalizationFieldMappingFactoryInterface::class, DenormalizationFieldMappingFactoryFactory::class); + return [ - new PetCollectionMapping(), - new PetMapping(), - new VaccinationMapping(), + new PetCollectionMapping($denormalizationFieldMappingFactory), + new PetMapping($denormalizationFieldMappingFactory), + new VaccinationMapping($denormalizationFieldMappingFactory), ]; } } diff --git a/src/container.php b/src/container.php index 7f776d5a..fe369444 100644 --- a/src/container.php +++ b/src/container.php @@ -12,7 +12,7 @@ foreach ($config['directories'] ?? [] as $directory) { if (!is_dir($directory)) { - mkdir($directory, 0775, true); + mkdir($directory, 0o775, true); } } diff --git a/tests/Integration/AbstractIntegrationTest.php b/tests/Integration/AbstractIntegrationTestCase.php similarity index 94% rename from tests/Integration/AbstractIntegrationTest.php rename to tests/Integration/AbstractIntegrationTestCase.php index f1c36b75..89136e71 100644 --- a/tests/Integration/AbstractIntegrationTest.php +++ b/tests/Integration/AbstractIntegrationTestCase.php @@ -4,10 +4,10 @@ namespace App\Tests\Integration; -use App\Tests\PhpServerTestHook; +use App\Tests\PhpServerExtension; use PHPUnit\Framework\TestCase; -abstract class AbstractIntegrationTest extends TestCase +abstract class AbstractIntegrationTestCase extends TestCase { /** * @var string @@ -120,12 +120,12 @@ private function geHttpHeaders(array $headerRows): array private function getEndpoint(): string { - $integrationEndpoint = getenv(PhpServerTestHook::ENV_INTEGRATION_ENDPOINT); + $integrationEndpoint = getenv(PhpServerExtension::ENV_INTEGRATION_ENDPOINT); if (false !== $integrationEndpoint) { return $integrationEndpoint; } - return sprintf(self::DEFAULT_INTEGRATION_ENDPOINT, PhpServerTestHook::PHP_SERVER_PORT); + return sprintf(self::DEFAULT_INTEGRATION_ENDPOINT, PhpServerExtension::PHP_SERVER_PORT); } } diff --git a/tests/Integration/CorsControllerTest.php b/tests/Integration/CorsControllerTest.php index 983d5d0e..f1297be2 100644 --- a/tests/Integration/CorsControllerTest.php +++ b/tests/Integration/CorsControllerTest.php @@ -9,7 +9,7 @@ * * @coversNothing */ -final class CorsControllerTest extends AbstractIntegrationTest +final class CorsControllerTest extends AbstractIntegrationTestCase { public function testCorsHeaderWithMatchingOrigin(): void { diff --git a/tests/Integration/OpenapiRequestHandlerTest.php b/tests/Integration/OpenapiRequestHandlerTest.php index fe373f88..028b0bd5 100644 --- a/tests/Integration/OpenapiRequestHandlerTest.php +++ b/tests/Integration/OpenapiRequestHandlerTest.php @@ -9,7 +9,7 @@ * * @coversNothing */ -final class OpenapiRequestHandlerTest extends AbstractIntegrationTest +final class OpenapiRequestHandlerTest extends AbstractIntegrationTestCase { public function testOpenapi(): void { diff --git a/tests/Integration/PetCrudRequestHandlerTest.php b/tests/Integration/PetCrudRequestHandlerTest.php index 51f558c4..3eba84d3 100644 --- a/tests/Integration/PetCrudRequestHandlerTest.php +++ b/tests/Integration/PetCrudRequestHandlerTest.php @@ -9,7 +9,7 @@ * * @coversNothing */ -final class PetCrudRequestHandlerTest extends AbstractIntegrationTest +final class PetCrudRequestHandlerTest extends AbstractIntegrationTestCase { public function testCreateWithUnsupportedAccept(): void { diff --git a/tests/Integration/PingRequestHandlerTest.php b/tests/Integration/PingRequestHandlerTest.php index 20e42743..c81257cc 100644 --- a/tests/Integration/PingRequestHandlerTest.php +++ b/tests/Integration/PingRequestHandlerTest.php @@ -9,7 +9,7 @@ * * @coversNothing */ -final class PingRequestHandlerTest extends AbstractIntegrationTest +final class PingRequestHandlerTest extends AbstractIntegrationTestCase { public function testPing(): void { diff --git a/tests/PhpServerTestHook.php b/tests/PhpServerExtension.php similarity index 74% rename from tests/PhpServerTestHook.php rename to tests/PhpServerExtension.php index db2c65f6..9f01462f 100644 --- a/tests/PhpServerTestHook.php +++ b/tests/PhpServerExtension.php @@ -4,9 +4,14 @@ namespace App\Tests; -use PHPUnit\Runner\BeforeTestHook; - -final class PhpServerTestHook implements BeforeTestHook +use PHPUnit\Event\TestRunner\ExecutionStarted; +use PHPUnit\Event\TestRunner\ExecutionStartedSubscriber; +use PHPUnit\Runner\Extension\Extension; +use PHPUnit\Runner\Extension\Facade; +use PHPUnit\Runner\Extension\ParameterCollection; +use PHPUnit\TextUI\Configuration\Configuration; + +final class PhpServerExtension implements ExecutionStartedSubscriber, Extension { public const PHP_SERVER_PORT = 49199; public const ENV_INTEGRATION_ENDPOINT = 'INTEGRATION_ENDPOINT'; @@ -20,7 +25,15 @@ public function __destruct() } } - public function executeBeforeTest(string $test): void + public function bootstrap( + Configuration $configuration, + Facade $facade, + ParameterCollection $parameters + ): void { + $facade->registerSubscriber($this); + } + + public function notify(ExecutionStarted $event): void { if (null !== $this->serverPid) { return; @@ -30,19 +43,10 @@ public function executeBeforeTest(string $test): void return; } - if (!$this->isIntegrationTest($test)) { - return; - } - $this->initialize(); $this->startServer(); } - private function isIntegrationTest(string $test): bool - { - return str_starts_with($test, 'App\\Tests\\Integration'); - } - private function initialize(): void { $consolePath = realpath(__DIR__.'/../bin/console'); diff --git a/tests/Unit/Collection/CollectionTest.php b/tests/Unit/Collection/CollectionTest.php index 99b44fb3..6a4137ab 100644 --- a/tests/Unit/Collection/CollectionTest.php +++ b/tests/Unit/Collection/CollectionTest.php @@ -19,12 +19,12 @@ public function testGetSet(): void { $collection = $this->getCollection(); - static::assertSame(0, $collection->getOffset()); - static::assertSame(20, $collection->getLimit()); - static::assertSame([], $collection->getFilters()); - static::assertSame([], $collection->getSort()); - static::assertSame(0, $collection->getCount()); - static::assertSame([], $collection->getItems()); + self::assertSame(0, $collection->getOffset()); + self::assertSame(20, $collection->getLimit()); + self::assertSame([], $collection->getFilters()); + self::assertSame([], $collection->getSort()); + self::assertSame(0, $collection->getCount()); + self::assertSame([], $collection->getItems()); $object = new \stdClass(); @@ -35,17 +35,16 @@ public function testGetSet(): void $collection->setCount(6); $collection->setItems([$object]); - static::assertSame(5, $collection->getOffset()); - static::assertSame(15, $collection->getLimit()); - static::assertSame(['name' => 'sample'], $collection->getFilters()); - static::assertSame(['name' => 'asc'], $collection->getSort()); - static::assertSame(6, $collection->getCount()); - static::assertSame([$object], $collection->getItems()); + self::assertSame(5, $collection->getOffset()); + self::assertSame(15, $collection->getLimit()); + self::assertSame(['name' => 'sample'], $collection->getFilters()); + self::assertSame(['name' => 'asc'], $collection->getSort()); + self::assertSame(6, $collection->getCount()); + self::assertSame([$object], $collection->getItems()); } protected function getCollection(): CollectionInterface { - return new class() extends AbstractCollection { - }; + return new class() extends AbstractCollection {}; } } diff --git a/tests/Unit/Mapping/Deserialization/PetCollectionMappingTest.php b/tests/Unit/Mapping/Deserialization/PetCollectionMappingTest.php index 10f723fd..776efc9a 100644 --- a/tests/Unit/Mapping/Deserialization/PetCollectionMappingTest.php +++ b/tests/Unit/Mapping/Deserialization/PetCollectionMappingTest.php @@ -7,7 +7,10 @@ use App\Collection\PetCollection; use App\Mapping\Deserialization\PetCollectionMapping; use Chubbyphp\Deserialization\Denormalizer\ConvertTypeFieldDenormalizer; -use Chubbyphp\Deserialization\Mapping\DenormalizationFieldMappingBuilder; +use Chubbyphp\Deserialization\Mapping\DenormalizationFieldMappingFactoryInterface; +use Chubbyphp\Deserialization\Mapping\DenormalizationFieldMappingInterface; +use Chubbyphp\Mock\Call; +use Chubbyphp\Mock\MockByCallsTrait; use PHPUnit\Framework\TestCase; /** @@ -17,16 +20,24 @@ */ final class PetCollectionMappingTest extends TestCase { + use MockByCallsTrait; + public function testGetClass(): void { - $mapping = new PetCollectionMapping(); + /** @var DenormalizationFieldMappingFactoryInterface|MockObject $denormalizationFieldMappingFactory */ + $denormalizationFieldMappingFactory = $this->getMockByCalls(DenormalizationFieldMappingFactoryInterface::class); + + $mapping = new PetCollectionMapping($denormalizationFieldMappingFactory); self::assertSame(PetCollection::class, $mapping->getClass()); } public function testGetDenormalizationFactory(): void { - $mapping = new PetCollectionMapping(); + /** @var DenormalizationFieldMappingFactoryInterface|MockObject $denormalizationFieldMappingFactory */ + $denormalizationFieldMappingFactory = $this->getMockByCalls(DenormalizationFieldMappingFactoryInterface::class); + + $mapping = new PetCollectionMapping($denormalizationFieldMappingFactory); $factory = $mapping->getDenormalizationFactory('/', 'petCollection'); @@ -37,17 +48,33 @@ public function testGetDenormalizationFactory(): void public function testGetDenormalizationFieldMappings(): void { - $mapping = new PetCollectionMapping(); + /** @var DenormalizationFieldMappingInterface|MockObject $offsetDenormalizationFieldMapping */ + $offsetDenormalizationFieldMapping = $this->getMockByCalls(DenormalizationFieldMappingInterface::class); + + /** @var DenormalizationFieldMappingInterface|MockObject $limitDenormalizationFieldMapping */ + $limitDenormalizationFieldMapping = $this->getMockByCalls(DenormalizationFieldMappingInterface::class); + + /** @var DenormalizationFieldMappingInterface|MockObject $filtersDenormalizationFieldMapping */ + $filtersDenormalizationFieldMapping = $this->getMockByCalls(DenormalizationFieldMappingInterface::class); + + /** @var DenormalizationFieldMappingInterface|MockObject $sortDenormalizationFieldMapping */ + $sortDenormalizationFieldMapping = $this->getMockByCalls(DenormalizationFieldMappingInterface::class); + + /** @var DenormalizationFieldMappingFactoryInterface|MockObject $denormalizationFieldMappingFactory */ + $denormalizationFieldMappingFactory = $this->getMockByCalls(DenormalizationFieldMappingFactoryInterface::class, [ + Call::create('createConvertType')->with('offset', ConvertTypeFieldDenormalizer::TYPE_INT, false, null)->willReturn($offsetDenormalizationFieldMapping), + Call::create('createConvertType')->with('limit', ConvertTypeFieldDenormalizer::TYPE_INT, false, null)->willReturn($limitDenormalizationFieldMapping), + Call::create('create')->with('filters', false, null, null)->willReturn($filtersDenormalizationFieldMapping), + Call::create('create')->with('sort', false, null, null)->willReturn($sortDenormalizationFieldMapping), + ]); + + $mapping = new PetCollectionMapping($denormalizationFieldMappingFactory); $fieldMappings = $mapping->getDenormalizationFieldMappings('/', 'petCollection'); - self::assertEquals([ - DenormalizationFieldMappingBuilder::createConvertType('offset', ConvertTypeFieldDenormalizer::TYPE_INT) - ->getMapping(), - DenormalizationFieldMappingBuilder::createConvertType('limit', ConvertTypeFieldDenormalizer::TYPE_INT) - ->getMapping(), - DenormalizationFieldMappingBuilder::create('filters')->getMapping(), - DenormalizationFieldMappingBuilder::create('sort')->getMapping(), - ], $fieldMappings); + self::assertSame($offsetDenormalizationFieldMapping, array_shift($fieldMappings)); + self::assertSame($limitDenormalizationFieldMapping, array_shift($fieldMappings)); + self::assertSame($filtersDenormalizationFieldMapping, array_shift($fieldMappings)); + self::assertSame($sortDenormalizationFieldMapping, array_shift($fieldMappings)); } } diff --git a/tests/Unit/Mapping/Deserialization/PetMappingTest.php b/tests/Unit/Mapping/Deserialization/PetMappingTest.php index 551938d4..f315c013 100644 --- a/tests/Unit/Mapping/Deserialization/PetMappingTest.php +++ b/tests/Unit/Mapping/Deserialization/PetMappingTest.php @@ -6,11 +6,13 @@ use App\Mapping\Deserialization\PetMapping; use App\Model\Pet; -use App\Model\Vaccination; -use Chubbyphp\Deserialization\Accessor\MethodAccessor; use Chubbyphp\Deserialization\Denormalizer\ConvertTypeFieldDenormalizer; use Chubbyphp\Deserialization\Denormalizer\Relation\EmbedManyFieldDenormalizer; -use Chubbyphp\Deserialization\Mapping\DenormalizationFieldMappingBuilder; +use Chubbyphp\Deserialization\Mapping\DenormalizationFieldMappingFactoryInterface; +use Chubbyphp\Deserialization\Mapping\DenormalizationFieldMappingInterface; +use Chubbyphp\Mock\Argument\ArgumentInstanceOf; +use Chubbyphp\Mock\Call; +use Chubbyphp\Mock\MockByCallsTrait; use PHPUnit\Framework\TestCase; /** @@ -20,16 +22,24 @@ */ final class PetMappingTest extends TestCase { + use MockByCallsTrait; + public function testGetClass(): void { - $mapping = new PetMapping(); + /** @var DenormalizationFieldMappingFactoryInterface|MockObject $denormalizationFieldMappingFactory */ + $denormalizationFieldMappingFactory = $this->getMockByCalls(DenormalizationFieldMappingFactoryInterface::class); + + $mapping = new PetMapping($denormalizationFieldMappingFactory); self::assertSame(Pet::class, $mapping->getClass()); } public function testGetDenormalizationFactory(): void { - $mapping = new PetMapping(); + /** @var DenormalizationFieldMappingFactoryInterface|MockObject $denormalizationFieldMappingFactory */ + $denormalizationFieldMappingFactory = $this->getMockByCalls(DenormalizationFieldMappingFactoryInterface::class); + + $mapping = new PetMapping($denormalizationFieldMappingFactory); $factory = $mapping->getDenormalizationFactory('/', 'pet'); @@ -40,20 +50,23 @@ public function testGetDenormalizationFactory(): void public function testGetDenormalizationFieldMappings(): void { - $mapping = new PetMapping(); - - $fieldMappings = $mapping->getDenormalizationFieldMappings('/', 'pet'); - - self::assertEquals([ - DenormalizationFieldMappingBuilder::createConvertType('name', ConvertTypeFieldDenormalizer::TYPE_STRING) - ->getMapping(), - DenormalizationFieldMappingBuilder::createConvertType('tag', ConvertTypeFieldDenormalizer::TYPE_STRING) - ->getMapping(), - DenormalizationFieldMappingBuilder::create( - 'vaccinations', - false, - new EmbedManyFieldDenormalizer(Vaccination::class, new MethodAccessor('vaccinations')) - )->getMapping(), - ], $fieldMappings); + /** @var DenormalizationFieldMappingInterface|MockObject $nameDenormalizationFieldMapping */ + $nameDenormalizationFieldMapping = $this->getMockByCalls(DenormalizationFieldMappingInterface::class); + + /** @var DenormalizationFieldMappingInterface|MockObject $tagDenormalizationFieldMapping */ + $tagDenormalizationFieldMapping = $this->getMockByCalls(DenormalizationFieldMappingInterface::class); + + /** @var DenormalizationFieldMappingInterface|MockObject $vaccinationsDenormalizationFieldMapping */ + $vaccinationsDenormalizationFieldMapping = $this->getMockByCalls(DenormalizationFieldMappingInterface::class); + + /** @var DenormalizationFieldMappingFactoryInterface|MockObject $denormalizationFieldMappingFactory */ + $denormalizationFieldMappingFactory = $this->getMockByCalls(DenormalizationFieldMappingFactoryInterface::class, [ + Call::create('createConvertType')->with('name', ConvertTypeFieldDenormalizer::TYPE_STRING, false, null)->willReturn($nameDenormalizationFieldMapping), + Call::create('createConvertType')->with('tag', ConvertTypeFieldDenormalizer::TYPE_STRING, false, null)->willReturn($tagDenormalizationFieldMapping), + Call::create('create')->with('vaccinations', false, new ArgumentInstanceOf(EmbedManyFieldDenormalizer::class), null)->willReturn($vaccinationsDenormalizationFieldMapping), + ]); + + $mapping = new PetMapping($denormalizationFieldMappingFactory); + $mapping->getDenormalizationFieldMappings('/', 'pet'); } } diff --git a/tests/Unit/Mapping/Deserialization/VaccinationMappingTest.php b/tests/Unit/Mapping/Deserialization/VaccinationMappingTest.php index daba13c3..0d90d15d 100644 --- a/tests/Unit/Mapping/Deserialization/VaccinationMappingTest.php +++ b/tests/Unit/Mapping/Deserialization/VaccinationMappingTest.php @@ -7,7 +7,10 @@ use App\Mapping\Deserialization\VaccinationMapping; use App\Model\Vaccination; use Chubbyphp\Deserialization\Denormalizer\ConvertTypeFieldDenormalizer; -use Chubbyphp\Deserialization\Mapping\DenormalizationFieldMappingBuilder; +use Chubbyphp\Deserialization\Mapping\DenormalizationFieldMappingFactoryInterface; +use Chubbyphp\Deserialization\Mapping\DenormalizationFieldMappingInterface; +use Chubbyphp\Mock\Call; +use Chubbyphp\Mock\MockByCallsTrait; use PHPUnit\Framework\TestCase; /** @@ -17,16 +20,24 @@ */ final class VaccinationMappingTest extends TestCase { + use MockByCallsTrait; + public function testGetClass(): void { - $mapping = new VaccinationMapping(); + /** @var DenormalizationFieldMappingFactoryInterface|MockObject $denormalizationFieldMappingFactory */ + $denormalizationFieldMappingFactory = $this->getMockByCalls(DenormalizationFieldMappingFactoryInterface::class); + + $mapping = new VaccinationMapping($denormalizationFieldMappingFactory); self::assertSame(Vaccination::class, $mapping->getClass()); } public function testGetDenormalizationFactory(): void { - $mapping = new VaccinationMapping(); + /** @var DenormalizationFieldMappingFactoryInterface|MockObject $denormalizationFieldMappingFactory */ + $denormalizationFieldMappingFactory = $this->getMockByCalls(DenormalizationFieldMappingFactoryInterface::class); + + $mapping = new VaccinationMapping($denormalizationFieldMappingFactory); $factory = $mapping->getDenormalizationFactory('/', 'vaccination'); @@ -37,13 +48,15 @@ public function testGetDenormalizationFactory(): void public function testGetDenormalizationFieldMappings(): void { - $mapping = new VaccinationMapping(); + /** @var DenormalizationFieldMappingInterface|MockObject $nameDenormalizationFieldMapping */ + $nameDenormalizationFieldMapping = $this->getMockByCalls(DenormalizationFieldMappingInterface::class); - $fieldMappings = $mapping->getDenormalizationFieldMappings('/', 'vaccination'); + /** @var DenormalizationFieldMappingFactoryInterface|MockObject $denormalizationFieldMappingFactory */ + $denormalizationFieldMappingFactory = $this->getMockByCalls(DenormalizationFieldMappingFactoryInterface::class, [ + Call::create('createConvertType')->with('name', ConvertTypeFieldDenormalizer::TYPE_STRING, false, null)->willReturn($nameDenormalizationFieldMapping), + ]); - self::assertEquals([ - DenormalizationFieldMappingBuilder::createConvertType('name', ConvertTypeFieldDenormalizer::TYPE_STRING) - ->getMapping(), - ], $fieldMappings); + $mapping = new VaccinationMapping($denormalizationFieldMappingFactory); + $mapping->getDenormalizationFieldMappings('/', 'vaccination'); } } diff --git a/tests/Unit/Mapping/Serialization/CollectionMappingTest.php b/tests/Unit/Mapping/Serialization/CollectionMappingTest.php index 864f59b8..78b1904b 100644 --- a/tests/Unit/Mapping/Serialization/CollectionMappingTest.php +++ b/tests/Unit/Mapping/Serialization/CollectionMappingTest.php @@ -33,7 +33,7 @@ public function testGetClass(): void $mapping = $this->getCollectionMapping($router); - static::assertSame($this->getClass(), $mapping->getClass()); + self::assertSame($this->getClass(), $mapping->getClass()); } public function testGetNormalizationType(): void @@ -43,7 +43,7 @@ public function testGetNormalizationType(): void $mapping = $this->getCollectionMapping($router); - static::assertSame($this->getNormalizationType(), $mapping->getNormalizationType()); + self::assertSame($this->getNormalizationType(), $mapping->getNormalizationType()); } public function testGetNormalizationFieldMappings(): void @@ -55,7 +55,7 @@ public function testGetNormalizationFieldMappings(): void $fieldMappings = $mapping->getNormalizationFieldMappings('/'); - static::assertEquals($this->getNormalizationFieldMappings('/'), $fieldMappings); + self::assertEquals($this->getNormalizationFieldMappings('/'), $fieldMappings); } public function testGetNormalizationEmbeddedFieldMappings(): void @@ -67,7 +67,7 @@ public function testGetNormalizationEmbeddedFieldMappings(): void $fieldMappings = $mapping->getNormalizationEmbeddedFieldMappings('/'); - static::assertEquals([ + self::assertEquals([ NormalizationFieldMappingBuilder::createEmbedMany('items')->getMapping(), ], $fieldMappings); } @@ -88,13 +88,12 @@ public function testGetNormalizationLinkMappings(): void $linkMappings = $mapping->getNormalizationLinkMappings('/'); - static::assertCount(2, $linkMappings); + self::assertCount(2, $linkMappings); - static::assertInstanceOf(NormalizationLinkMappingInterface::class, $linkMappings[0]); - static::assertInstanceOf(NormalizationLinkMappingInterface::class, $linkMappings[1]); + self::assertInstanceOf(NormalizationLinkMappingInterface::class, $linkMappings[0]); + self::assertInstanceOf(NormalizationLinkMappingInterface::class, $linkMappings[1]); - $object = new class() extends AbstractCollection { - }; + $object = new class() extends AbstractCollection {}; $object->setOffset(0); $object->setLimit(20); @@ -113,7 +112,7 @@ public function testGetNormalizationLinkMappings(): void $list = $linkMappings[0]->getLinkNormalizer()->normalizeLink('/', $object, $context); $create = $linkMappings[1]->getLinkNormalizer()->normalizeLink('/', $object, $context); - static::assertSame([ + self::assertSame([ 'href' => sprintf('%s?offset=0&limit=20', $this->getCollectionPath()), 'templated' => false, 'rel' => [], @@ -122,7 +121,7 @@ public function testGetNormalizationLinkMappings(): void ], ], $list); - static::assertSame([ + self::assertSame([ 'href' => $this->getCollectionPath(), 'templated' => false, 'rel' => [], diff --git a/tests/Unit/Mapping/Serialization/ModelMappingTest.php b/tests/Unit/Mapping/Serialization/ModelMappingTest.php index a39f208a..12caa806 100644 --- a/tests/Unit/Mapping/Serialization/ModelMappingTest.php +++ b/tests/Unit/Mapping/Serialization/ModelMappingTest.php @@ -31,7 +31,7 @@ public function testGetClass(): void $mapping = $this->getModelMapping($router); - static::assertSame($this->getClass(), $mapping->getClass()); + self::assertSame($this->getClass(), $mapping->getClass()); } public function testGetNormalizationType(): void @@ -41,7 +41,7 @@ public function testGetNormalizationType(): void $mapping = $this->getModelMapping($router); - static::assertSame($this->getNormalizationType(), $mapping->getNormalizationType()); + self::assertSame($this->getNormalizationType(), $mapping->getNormalizationType()); } public function testGetNormalizationFieldMappings(): void @@ -53,7 +53,7 @@ public function testGetNormalizationFieldMappings(): void $fieldMappings = $mapping->getNormalizationFieldMappings('/'); - static::assertEquals([ + self::assertEquals([ NormalizationFieldMappingBuilder::create('id')->getMapping(), NormalizationFieldMappingBuilder::createDateTime('createdAt', \DateTime::ATOM)->getMapping(), NormalizationFieldMappingBuilder::createDateTime('updatedAt', \DateTime::ATOM)->getMapping(), @@ -69,7 +69,7 @@ public function testGetNormalizationEmbeddedFieldMappings(): void $fieldMappings = $mapping->getNormalizationEmbeddedFieldMappings('/'); - static::assertEquals([], $fieldMappings); + self::assertEquals([], $fieldMappings); } public function testGetNormalizationLinkMappings(): void @@ -91,11 +91,11 @@ public function testGetNormalizationLinkMappings(): void $linkMappings = $mapping->getNormalizationLinkMappings('/'); - static::assertCount(3, $linkMappings); + self::assertCount(3, $linkMappings); - static::assertInstanceOf(NormalizationLinkMappingInterface::class, $linkMappings[0]); - static::assertInstanceOf(NormalizationLinkMappingInterface::class, $linkMappings[1]); - static::assertInstanceOf(NormalizationLinkMappingInterface::class, $linkMappings[2]); + self::assertInstanceOf(NormalizationLinkMappingInterface::class, $linkMappings[0]); + self::assertInstanceOf(NormalizationLinkMappingInterface::class, $linkMappings[1]); + self::assertInstanceOf(NormalizationLinkMappingInterface::class, $linkMappings[2]); /** @var MockObject|ModelInterface $model */ $model = $this->getMockByCalls(ModelInterface::class, [ @@ -111,7 +111,7 @@ public function testGetNormalizationLinkMappings(): void $update = $linkMappings[1]->getLinkNormalizer()->normalizeLink('/', $model, $context); $delete = $linkMappings[2]->getLinkNormalizer()->normalizeLink('/', $model, $context); - static::assertSame([ + self::assertSame([ 'href' => sprintf($this->getModelPath(), 'f183c7ff-7683-451e-807c-b916d9b5cf86'), 'templated' => false, 'rel' => [], @@ -120,7 +120,7 @@ public function testGetNormalizationLinkMappings(): void ], ], $read); - static::assertSame([ + self::assertSame([ 'href' => sprintf($this->getModelPath(), 'f183c7ff-7683-451e-807c-b916d9b5cf86'), 'templated' => false, 'rel' => [], @@ -129,7 +129,7 @@ public function testGetNormalizationLinkMappings(): void ], ], $update); - static::assertSame([ + self::assertSame([ 'href' => sprintf($this->getModelPath(), 'f183c7ff-7683-451e-807c-b916d9b5cf86'), 'templated' => false, 'rel' => [], diff --git a/tests/Unit/ServiceFactory/Deserialization/DenormalizationObjectMappingsFactoryTest.php b/tests/Unit/ServiceFactory/Deserialization/DenormalizationObjectMappingsFactoryTest.php index 24574995..795df2d7 100644 --- a/tests/Unit/ServiceFactory/Deserialization/DenormalizationObjectMappingsFactoryTest.php +++ b/tests/Unit/ServiceFactory/Deserialization/DenormalizationObjectMappingsFactoryTest.php @@ -4,12 +4,12 @@ namespace App\Tests\Unit\ServiceFactory\Deserialization; -use App\Mapping\Deserialization\PetCollectionMapping; -use App\Mapping\Deserialization\PetMapping; -use App\Mapping\Deserialization\VaccinationMapping; use App\ServiceFactory\Deserialization\DenormalizationObjectMappingsFactory; +use Chubbyphp\Deserialization\Mapping\DenormalizationFieldMappingFactoryInterface; +use Chubbyphp\Mock\Call; use Chubbyphp\Mock\MockByCallsTrait; use PHPUnit\Framework\TestCase; +use Psr\Container\ContainerInterface; /** * @covers \App\ServiceFactory\Deserialization\DenormalizationObjectMappingsFactory @@ -22,14 +22,16 @@ final class DenormalizationObjectMappingsFactoryTest extends TestCase public function testInvoke(): void { - $factory = new DenormalizationObjectMappingsFactory(); + /** @var DenormalizationFieldMappingFactoryInterface|MockObject $denormalizationFieldMappingFactory */ + $denormalizationFieldMappingFactory = $this->getMockByCalls(DenormalizationFieldMappingFactoryInterface::class); - $service = $factory(); + /** @var ContainerInterface $container */ + $container = $this->getMockByCalls(ContainerInterface::class, [ + Call::create('has')->with(DenormalizationFieldMappingFactoryInterface::class)->willReturn(true), + Call::create('get')->with(DenormalizationFieldMappingFactoryInterface::class)->willReturn($denormalizationFieldMappingFactory), + ]); - self::assertEquals([ - new PetCollectionMapping(), - new PetMapping(), - new VaccinationMapping(), - ], $service); + $factory = new DenormalizationObjectMappingsFactory(); + $factory($container); } } diff --git a/tests/Unit/ServiceFactory/Logger/LoggerFactoryTest.php b/tests/Unit/ServiceFactory/Logger/LoggerFactoryTest.php index e2ae9ddc..6aedf3d2 100644 --- a/tests/Unit/ServiceFactory/Logger/LoggerFactoryTest.php +++ b/tests/Unit/ServiceFactory/Logger/LoggerFactoryTest.php @@ -11,7 +11,9 @@ use Monolog\Formatter\LogstashFormatter; use Monolog\Handler\BufferHandler; use Monolog\Handler\StreamHandler; +use Monolog\Level; use Monolog\Logger; +use Monolog\LogRecord; use PHPUnit\Framework\TestCase; use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; @@ -33,7 +35,7 @@ public function testInvoke(): void 'monolog' => [ 'name' => 'test', 'path' => $path, - 'level' => Logger::NOTICE, + 'level' => Level::Notice, ], ]; @@ -65,13 +67,15 @@ public function testInvoke(): void self::assertInstanceOf(StreamHandler::class, $streamHandler); self::assertSame($path, $streamHandler->getUrl()); - self::assertSame(Logger::NOTICE, $streamHandler->getLevel()); + self::assertSame(Level::Notice, $streamHandler->getLevel()); /** @var LogstashFormatter $logstashFormatter */ $logstashFormatter = $streamHandler->getFormatter(); self::assertInstanceOf(LogstashFormatter::class, $logstashFormatter); - self::assertStringContainsString('"type":"app"', $logstashFormatter->format([])); + $record = new LogRecord(new \DateTimeImmutable('2023-12-31T12:15:00Z'), 'channel', Level::Notice, 'message'); + + self::assertStringContainsString('"type":"app"', $logstashFormatter->format($record)); } }