diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e460ea6c..edb33f90 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,13 +13,15 @@ jobs: strategy: matrix: os: [ 'ubuntu-18.04' ] #, macos-latest, windows-latest ] - php-version: [ '7.2', '7.3', '7.4' ] + php-version: [ '7.3', '7.4', '8.0' ] name: PHP ${{ matrix.php-version }} on OS ${{ matrix.os }} steps: - name: Acquire sources uses: actions/checkout@v2 + with: + fetch-depth: 2 # With GHA's "services", you cannot map volumes to your codebase BEFORE checking out the codebase. # So, let's use `docker-compose` to bring in services AFTER checking out the code. @@ -32,8 +34,7 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php-version }} - # Select PHPUnit version suitable for PHP 7.2. - tools: composer, phpunit:^8.5 + tools: composer, phpunit:^9.5 # Cache Composer Dependencies # https://github.com/marketplace/actions/setup-php-action#cache-composer-dependencies @@ -51,22 +52,21 @@ jobs: run: composer install - name: Run code style checks - run: composer run style + run: composer run check-style - name: Run tests run: composer run test - # https://github.com/php-coveralls/php-coveralls#github-actions - - name: Upload coverage results to Coveralls - if: always() && matrix.php-version == '7.4' - env: - COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - composer global require php-coveralls/php-coveralls - php-coveralls --coverage_clover=build/logs/clover.xml -v + # https://github.com/codecov/codecov-action + - name: Upload coverage results to Codecov + uses: codecov/codecov-action@v1 + if: always() && (matrix.php-version == '7.4' || matrix.php-version == '8.0') + with: + files: ./build/logs/clover.xml + fail_ci_if_error: true - name: Upload coverage results to Scrutinizer CI - if: always() && matrix.php-version == '7.4' + if: always() && (matrix.php-version == '7.4' || matrix.php-version == '8.0') run: | echo "Git HEAD ref:" git log --pretty=%P -n1 HEAD diff --git a/.scrutinizer.yml b/.scrutinizer.yml index bb58996e..4e70539a 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -30,7 +30,7 @@ build: analysis: environment: php: - version: 7.4 + version: 8.0 tests: override: - php-scrutinizer-run --enable-security-analysis @@ -39,4 +39,10 @@ build: # https://scrutinizer-ci.com/docs/tools/external-code-coverage/ tools: - external_code_coverage: true + external_code_coverage: + + enabled: true + + # Scrutinizer will wait for two code coverage submissions + # in order to cover both PHP7 and PHP8. + runs: 2 diff --git a/CHANGES.rst b/CHANGES.rst index ae94ff04..13b00782 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,10 @@ Unreleased ========== +- Added support for PHP 8.0 + +- Removed support for PHP 7.2, it has reached end of life + - Bumped required guzzle http client dependency to ``^7.2`` 2020/09/28 1.1.0 diff --git a/DEVELOP.rst b/DEVELOP.rst index 0a10a9b6..ca6c4a9a 100644 --- a/DEVELOP.rst +++ b/DEVELOP.rst @@ -81,14 +81,22 @@ Installation Install prerequisites:: - brew install php@7.2 composer + # Install different PHP releases and Composer. + brew install php@7.3 php@7.4 php@8.0 brew-php-switcher composer + + # Select PHP version. + brew-php-switcher 7.3 + brew-php-switcher 7.4 + brew-php-switcher 8.0 + + # Install `xdebug` extension into each environment for tracking code coverage. pecl install xdebug Get the sources:: git clone git@github.com:crate/crate-pdo.git -Setup environment:: +Setup project dependencies:: composer install @@ -105,11 +113,25 @@ Running the Tests --mount type=bind,source=$PWD/test/provisioning/truststore,target=/vagrant/test/provisioning/truststore \ --publish 4200:4200 --publish 5432:5432 crate/crate:nightly - # Run test suite + # Run test suite on current/default version of PHP composer run test + # Run tests on both PHP7 and PHP8 to get the full picture of coverage + composer run multicover + open build/multicover/html/index.html + + +Invoke code style checks +======================== + +:: + # Run code style checks - composer run style + composer run check-style + + # Some code style quirks can be automatically fixed + composer run fix-style + **************************** diff --git a/README.rst b/README.rst index b8c3c001..8c3bcaaf 100644 --- a/README.rst +++ b/README.rst @@ -10,8 +10,8 @@ CrateDB PDO Adapter :target: https://github.com/crate/crate-pdo/actions?workflow=Docs :alt: Build status (documentation) -.. image:: https://coveralls.io/repos/github/crate/crate-pdo/badge.svg?branch=main - :target: https://coveralls.io/github/crate/crate-pdo +.. image:: https://codecov.io/gh/crate/crate-pdo/branch/main/graph/badge.svg + :target: https://app.codecov.io/gh/crate/crate-pdo :alt: Coverage .. image:: https://scrutinizer-ci.com/g/crate/crate-pdo/badges/quality-score.png?b=main @@ -22,9 +22,13 @@ CrateDB PDO Adapter :target: https://packagist.org/packages/crate/crate-pdo :alt: Latest stable version -.. image:: https://poser.pugx.org/crate/crate-pdo/downloads +.. image:: https://img.shields.io/badge/PHP-7.3%2C%207.4%2C%208.0-green.svg :target: https://packagist.org/packages/crate/crate-pdo - :alt: Total downloads + :alt: Supported PHP versions + +.. image:: https://poser.pugx.org/crate/crate-pdo/d/monthly + :target: https://packagist.org/packages/crate/crate-pdo + :alt: Monthly downloads .. image:: https://poser.pugx.org/crate/crate-pdo/license :target: https://packagist.org/packages/crate/crate-pdo @@ -48,7 +52,7 @@ Installation The CrateDB PDO adapter is available as a Composer package. Install it like:: - composer add crate/crate-pdo + composer require crate/crate-pdo See the `installation documentation`_ for more info. diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 00000000..8b485e7c --- /dev/null +++ b/codecov.yml @@ -0,0 +1,9 @@ +# https://docs.codecov.io/docs/common-recipe-list +# https://docs.codecov.io/docs/commit-status#patch-status + +coverage: + status: + project: + default: + target: 85% # the required coverage value + threshold: 3% # the leniency in hitting the target diff --git a/composer.json b/composer.json index 74ccee3c..d8c0b47a 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ "homepage": "https://github.com/crate/crate-pdo", "keywords": ["database", "pdo", "cratedb"], "require": { - "php": "^7.2", + "php": "^7.3|^8.0|^8.1", "ext-pdo": "*", "guzzlehttp/guzzle": "^7.2" }, @@ -23,7 +23,7 @@ } }, "require-dev": { - "phpunit/phpunit": "^8.5", + "phpunit/phpunit": "^9.5", "phpstan/phpstan": "^0.12", "squizlabs/php_codesniffer": "^3.5" }, @@ -35,6 +35,9 @@ }, "scripts": { "test": "XDEBUG_MODE=coverage phpunit --coverage-clover build/logs/clover.xml", - "style": "phpcs" + "coverage-html": "XDEBUG_MODE=coverage phpunit --coverage-html build/logs/html", + "multicover": "./devtools/php-multicover.sh", + "check-style": "phpcs", + "fix-style": "phpcbf" } } diff --git a/composer.lock b/composer.lock index e3c34e3c..6a89f3e7 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ce7d8996624dfe2cd2773b44603139db", + "content-hash": "788e6343538a0ba45e412100c38fac81", "packages": [ { "name": "guzzlehttp/guzzle", @@ -516,6 +516,62 @@ ], "time": "2020-11-13T09:40:50+00:00" }, + { + "name": "nikic/php-parser", + "version": "v4.10.4", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/c6d052fc58cb876152f89f532b95a8d7907e7f0e", + "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.10.4" + }, + "time": "2020-12-20T10:01:03+00:00" + }, { "name": "phar-io/manifest", "version": "2.0.1", @@ -578,16 +634,16 @@ }, { "name": "phar-io/version", - "version": "3.0.4", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "e4782611070e50613683d2b9a57730e9a3ba5451" + "reference": "bae7c545bef187884426f042434e561ab1ddb182" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/e4782611070e50613683d2b9a57730e9a3ba5451", - "reference": "e4782611070e50613683d2b9a57730e9a3ba5451", + "url": "https://api.github.com/repos/phar-io/version/zipball/bae7c545bef187884426f042434e561ab1ddb182", + "reference": "bae7c545bef187884426f042434e561ab1ddb182", "shasum": "" }, "require": { @@ -623,9 +679,9 @@ "description": "Library for handling version information and constraints", "support": { "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.0.4" + "source": "https://github.com/phar-io/version/tree/3.1.0" }, - "time": "2020-12-13T23:18:30+00:00" + "time": "2021-02-23T14:00:09+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -914,40 +970,44 @@ }, { "name": "phpunit/php-code-coverage", - "version": "7.0.14", + "version": "9.2.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "bb7c9a210c72e4709cdde67f8b7362f672f2225c" + "reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/bb7c9a210c72e4709cdde67f8b7362f672f2225c", - "reference": "bb7c9a210c72e4709cdde67f8b7362f672f2225c", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f3e026641cc91909d421802dd3ac7827ebfd97e1", + "reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1", "shasum": "" }, "require": { "ext-dom": "*", + "ext-libxml": "*", "ext-xmlwriter": "*", - "php": ">=7.2", - "phpunit/php-file-iterator": "^2.0.2", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^3.1.1 || ^4.0", - "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^4.2.2", - "sebastian/version": "^2.0.1", - "theseer/tokenizer": "^1.1.3" + "nikic/php-parser": "^4.10.2", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-text-template": "^2.0.2", + "sebastian/code-unit-reverse-lookup": "^2.0.2", + "sebastian/complexity": "^2.0", + "sebastian/environment": "^5.1.2", + "sebastian/lines-of-code": "^1.0.3", + "sebastian/version": "^3.0.1", + "theseer/tokenizer": "^1.2.0" }, "require-dev": { - "phpunit/phpunit": "^8.2.2" + "phpunit/phpunit": "^9.3" }, "suggest": { - "ext-xdebug": "^2.7.2" + "ext-pcov": "*", + "ext-xdebug": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "7.0-dev" + "dev-master": "9.2-dev" } }, "autoload": { @@ -975,7 +1035,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/7.0.14" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.5" }, "funding": [ { @@ -983,32 +1043,32 @@ "type": "github" } ], - "time": "2020-12-02T13:39:03+00:00" + "time": "2020-11-28T06:44:49+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "2.0.3", + "version": "3.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357" + "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/4b49fb70f067272b659ef0174ff9ca40fdaa6357", - "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/aa4be8575f26070b100fccb67faabb28f21f66f8", + "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^8.5" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -1035,7 +1095,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.3" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.5" }, "funding": [ { @@ -1043,26 +1103,38 @@ "type": "github" } ], - "time": "2020-11-30T08:25:21+00:00" + "time": "2020-09-28T05:57:25+00:00" }, { - "name": "phpunit/php-text-template", - "version": "1.2.1", + "name": "phpunit/php-invoker", + "version": "3.1.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, "autoload": { "classmap": [ "src/" @@ -1079,41 +1151,47 @@ "role": "lead" } ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", "keywords": [ - "template" + "process" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1" + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" }, - "time": "2015-06-21T13:50:34+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" }, { - "name": "phpunit/php-timer", - "version": "2.1.3", + "name": "phpunit/php-text-template", + "version": "2.0.4", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662" + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662", - "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^8.5" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -1132,14 +1210,14 @@ "role": "lead" } ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", "keywords": [ - "timer" + "template" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.3" + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" }, "funding": [ { @@ -1147,33 +1225,32 @@ "type": "github" } ], - "time": "2020-11-30T08:20:02+00:00" + "time": "2020-10-26T05:33:50+00:00" }, { - "name": "phpunit/php-token-stream", - "version": "3.1.2", + "name": "phpunit/php-timer", + "version": "5.0.3", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "472b687829041c24b25f475e14c2f38a09edf1c2" + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/472b687829041c24b25f475e14c2f38a09edf1c2", - "reference": "472b687829041c24b25f475e14c2f38a09edf1c2", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", "shasum": "" }, "require": { - "ext-tokenizer": "*", - "php": ">=7.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^7.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -1188,17 +1265,18 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", "keywords": [ - "tokenizer" + "timer" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", - "source": "https://github.com/sebastianbergmann/php-token-stream/tree/3.1.2" + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" }, "funding": [ { @@ -1206,21 +1284,20 @@ "type": "github" } ], - "abandoned": true, - "time": "2020-11-30T08:38:46+00:00" + "time": "2020-10-26T13:16:10+00:00" }, { "name": "phpunit/phpunit", - "version": "8.5.14", + "version": "9.5.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "c25f79895d27b6ecd5abfa63de1606b786a461a3" + "reference": "f661659747f2f87f9e72095bb207bceb0f151cb4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c25f79895d27b6ecd5abfa63de1606b786a461a3", - "reference": "c25f79895d27b6ecd5abfa63de1606b786a461a3", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f661659747f2f87f9e72095bb207bceb0f151cb4", + "reference": "f661659747f2f87f9e72095bb207bceb0f151cb4", "shasum": "" }, "require": { @@ -1231,32 +1308,35 @@ "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.10.0", + "myclabs/deep-copy": "^1.10.1", "phar-io/manifest": "^2.0.1", "phar-io/version": "^3.0.2", - "php": ">=7.2", - "phpspec/prophecy": "^1.10.3", - "phpunit/php-code-coverage": "^7.0.12", - "phpunit/php-file-iterator": "^2.0.2", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^2.1.2", - "sebastian/comparator": "^3.0.2", - "sebastian/diff": "^3.0.2", - "sebastian/environment": "^4.2.3", - "sebastian/exporter": "^3.1.2", - "sebastian/global-state": "^3.0.0", - "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^2.0.1", - "sebastian/type": "^1.1.3", - "sebastian/version": "^2.0.1" + "php": ">=7.3", + "phpspec/prophecy": "^1.12.1", + "phpunit/php-code-coverage": "^9.2.3", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.3", + "phpunit/php-timer": "^5.0.2", + "sebastian/cli-parser": "^1.0.1", + "sebastian/code-unit": "^1.0.6", + "sebastian/comparator": "^4.0.5", + "sebastian/diff": "^4.0.3", + "sebastian/environment": "^5.1.3", + "sebastian/exporter": "^4.0.3", + "sebastian/global-state": "^5.0.1", + "sebastian/object-enumerator": "^4.0.3", + "sebastian/resource-operations": "^3.0.3", + "sebastian/type": "^2.3", + "sebastian/version": "^3.0.2" }, "require-dev": { - "ext-pdo": "*" + "ext-pdo": "*", + "phpspec/prophecy-phpunit": "^2.0.1" }, "suggest": { "ext-soap": "*", - "ext-xdebug": "*", - "phpunit/php-invoker": "^2.0.0" + "ext-xdebug": "*" }, "bin": [ "phpunit" @@ -1264,12 +1344,15 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "8.5-dev" + "dev-master": "9.5-dev" } }, "autoload": { "classmap": [ "src/" + ], + "files": [ + "src/Framework/Assert/Functions.php" ] }, "notification-url": "https://packagist.org/downloads/", @@ -1292,7 +1375,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.14" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.2" }, "funding": [ { @@ -1304,32 +1387,144 @@ "type": "github" } ], - "time": "2021-01-17T07:37:30+00:00" + "time": "2021-02-02T14:45:58+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:08:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619" + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619", - "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", "shasum": "" }, "require": { - "php": ">=5.6" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^8.5" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -1351,7 +1546,7 @@ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "support": { "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2" + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" }, "funding": [ { @@ -1359,34 +1554,34 @@ "type": "github" } ], - "time": "2020-11-30T08:15:22+00:00" + "time": "2020-09-28T05:30:19+00:00" }, { "name": "sebastian/comparator", - "version": "3.0.3", + "version": "4.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "1071dfcef776a57013124ff35e1fc41ccd294758" + "reference": "55f4261989e546dc112258c7a75935a81a7ce382" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758", - "reference": "1071dfcef776a57013124ff35e1fc41ccd294758", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", + "reference": "55f4261989e546dc112258c7a75935a81a7ce382", "shasum": "" }, "require": { - "php": ">=7.1", - "sebastian/diff": "^3.0", - "sebastian/exporter": "^3.1" + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" }, "require-dev": { - "phpunit/phpunit": "^8.5" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1425,7 +1620,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.3" + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" }, "funding": [ { @@ -1433,33 +1628,90 @@ "type": "github" } ], - "time": "2020-11-30T08:04:30+00:00" + "time": "2020-10-26T15:49:45+00:00" + }, + { + "name": "sebastian/complexity", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.7", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:52:27+00:00" }, { "name": "sebastian/diff", - "version": "3.0.3", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211" + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211", - "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^7.5 || ^8.0", - "symfony/process": "^2 || ^3.3 || ^4" + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1491,7 +1743,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/3.0.3" + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" }, "funding": [ { @@ -1499,27 +1751,27 @@ "type": "github" } ], - "time": "2020-11-30T07:59:04+00:00" + "time": "2020-10-26T13:10:38+00:00" }, { "name": "sebastian/environment", - "version": "4.2.4", + "version": "5.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0" + "reference": "388b6ced16caa751030f6a69e588299fa09200ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", - "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac", + "reference": "388b6ced16caa751030f6a69e588299fa09200ac", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^7.5" + "phpunit/phpunit": "^9.3" }, "suggest": { "ext-posix": "*" @@ -1527,7 +1779,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "5.1-dev" } }, "autoload": { @@ -1554,7 +1806,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/4.2.4" + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3" }, "funding": [ { @@ -1562,34 +1814,34 @@ "type": "github" } ], - "time": "2020-11-30T07:53:42+00:00" + "time": "2020-09-28T05:52:38+00:00" }, { "name": "sebastian/exporter", - "version": "3.1.3", + "version": "4.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e" + "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/6b853149eab67d4da22291d36f5b0631c0fd856e", - "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/d89cc98761b8cb5a1a235a6b703ae50d34080e65", + "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65", "shasum": "" }, "require": { - "php": ">=7.0", - "sebastian/recursion-context": "^3.0" + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" }, "require-dev": { "ext-mbstring": "*", - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1.x-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1631,7 +1883,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.3" + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.3" }, "funding": [ { @@ -1639,30 +1891,30 @@ "type": "github" } ], - "time": "2020-11-30T07:47:53+00:00" + "time": "2020-09-28T05:24:23+00:00" }, { "name": "sebastian/global-state", - "version": "3.0.1", + "version": "5.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "474fb9edb7ab891665d3bfc6317f42a0a150454b" + "reference": "a90ccbddffa067b51f574dea6eb25d5680839455" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/474fb9edb7ab891665d3bfc6317f42a0a150454b", - "reference": "474fb9edb7ab891665d3bfc6317f42a0a150454b", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/a90ccbddffa067b51f574dea6eb25d5680839455", + "reference": "a90ccbddffa067b51f574dea6eb25d5680839455", "shasum": "" }, "require": { - "php": ">=7.2", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^8.0" + "phpunit/phpunit": "^9.3" }, "suggest": { "ext-uopz": "*" @@ -1670,7 +1922,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -1695,7 +1947,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/3.0.1" + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.2" }, "funding": [ { @@ -1703,34 +1955,91 @@ "type": "github" } ], - "time": "2020-11-30T07:43:24+00:00" + "time": "2020-10-26T15:55:19+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.6", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-28T06:42:11+00:00" }, { "name": "sebastian/object-enumerator", - "version": "3.0.4", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2" + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", - "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", "shasum": "" }, "require": { - "php": ">=7.0", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0.x-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1752,7 +2061,7 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4" + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" }, "funding": [ { @@ -1760,32 +2069,32 @@ "type": "github" } ], - "time": "2020-11-30T07:40:27+00:00" + "time": "2020-10-26T13:12:34+00:00" }, { "name": "sebastian/object-reflector", - "version": "1.1.2", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d" + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", - "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", "shasum": "" }, "require": { - "php": ">=7.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -1807,7 +2116,7 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2" + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" }, "funding": [ { @@ -1815,32 +2124,32 @@ "type": "github" } ], - "time": "2020-11-30T07:37:18+00:00" + "time": "2020-10-26T13:14:26+00:00" }, { "name": "sebastian/recursion-context", - "version": "3.0.1", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb" + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb", - "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", "shasum": "" }, "require": { - "php": ">=7.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0.x-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1870,7 +2179,7 @@ "homepage": "http://www.github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" }, "funding": [ { @@ -1878,29 +2187,32 @@ "type": "github" } ], - "time": "2020-11-30T07:34:24+00:00" + "time": "2020-10-26T13:17:30+00:00" }, { "name": "sebastian/resource-operations", - "version": "2.0.2", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3" + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3", - "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -1922,7 +2234,7 @@ "homepage": "https://www.github.com/sebastianbergmann/resource-operations", "support": { "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.2" + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" }, "funding": [ { @@ -1930,32 +2242,32 @@ "type": "github" } ], - "time": "2020-11-30T07:30:19+00:00" + "time": "2020-09-28T06:45:17+00:00" }, { "name": "sebastian/type", - "version": "1.1.4", + "version": "2.3.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "0150cfbc4495ed2df3872fb31b26781e4e077eb4" + "reference": "81cd61ab7bbf2de744aba0ea61fae32f721df3d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/0150cfbc4495ed2df3872fb31b26781e4e077eb4", - "reference": "0150cfbc4495ed2df3872fb31b26781e4e077eb4", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/81cd61ab7bbf2de744aba0ea61fae32f721df3d2", + "reference": "81cd61ab7bbf2de744aba0ea61fae32f721df3d2", "shasum": "" }, "require": { - "php": ">=7.2" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^8.2" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-master": "2.3-dev" } }, "autoload": { @@ -1978,7 +2290,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/1.1.4" + "source": "https://github.com/sebastianbergmann/type/tree/2.3.1" }, "funding": [ { @@ -1986,29 +2298,29 @@ "type": "github" } ], - "time": "2020-11-30T07:25:11+00:00" + "time": "2020-10-26T13:18:59+00:00" }, { "name": "sebastian/version", - "version": "2.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + "reference": "c6c1022351a901512170118436c764e473f6de8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", "shasum": "" }, "require": { - "php": ">=5.6" + "php": ">=7.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -2031,9 +2343,15 @@ "homepage": "https://github.com/sebastianbergmann/version", "support": { "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/master" + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" }, - "time": "2016-10-03T07:35:21+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" }, { "name": "squizlabs/php_codesniffer", @@ -2280,7 +2598,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^7.2", + "php": "^7.3|^8.0|^8.1", "ext-pdo": "*" }, "platform-dev": [], diff --git a/devtools/php-multicover.sh b/devtools/php-multicover.sh new file mode 100755 index 00000000..5c45d6aa --- /dev/null +++ b/devtools/php-multicover.sh @@ -0,0 +1,65 @@ +#!/bin/sh +# +# About +# ===== +# +# Run tests with coverage on both PHP7 and PHP8, +# merge coverage reports and render them as HTML. +# +# Please adjust the paths to the PHP interpreters +# to fit your needs. Make sure to `pecl install xdebug` +# in both PHP7 and PHP8 environments beforehand. +# +# Setup +# ===== +# +# Install different PHP releases and Composer:: +# +# brew install php@7.3 php@7.4 php@8.0 brew-php-switcher composer +# +# Select PHP version:: +# +# brew-php-switcher 7.3 +# brew-php-switcher 7.4 +# brew-php-switcher 8.0 +# +# Install `xdebug` extension into each environment for tracking code coverage:: +# +# pecl install xdebug +# +# Install `phpunit-merger`:: +# +# composer require --dev nimut/phpunit-merger +# +# Please make sure to remove it before committing as it is currently not available for PHP8:: +# +# composer remove --dev nimut/phpunit-merger +# + +# Define shortcuts to PHP variants. +php7=/usr/bin/php7.4 +php8=/usr/bin/php8.0 + +# Define shortcuts to vendor scripts. +phpunit="$(pwd)/vendor/bin/phpunit" +phpunit_merger="$(pwd)/vendor/bin/phpunit-merger" + +# Prepare output directories. +mkdir -p build/multicover/reports build/multicover/html +rm -rf build/multicover/reports/* build/multicover/html/* + +# Enable coverage tracing. +export XDEBUG_MODE=coverage + +# Run tests with PHP coverage output on both PHP7 and PHP8. +echo Running tests with coverage on PHP7 +$php7 $phpunit --coverage-php build/multicover/reports/clover-php7.php +echo; echo + +echo Running tests with coverage on PHP8 +$php8 $phpunit --coverage-php build/multicover/reports/clover-php8.php +echo; echo + +# Merge coverage reports and generate HTML output. +echo Merging test reports +$php7 $phpunit_merger coverage build/multicover/reports --html=build/multicover/html /dev/null diff --git a/docs/getting-started.rst b/docs/getting-started.rst index e8d68d20..51598d4e 100644 --- a/docs/getting-started.rst +++ b/docs/getting-started.rst @@ -26,7 +26,7 @@ The driver is available as a package at `crate/crate-pdo`_. Add the driver package to your project's `composer.json`_:: - composer add crate/crate-pdo + composer require crate/crate-pdo .. _install: diff --git a/phpunit.xml.dist b/phpunit.xml.dist index e6e7e42b..c8a4d515 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,26 +1,28 @@ - - - ./test/CrateTest - - - ./test/CrateIntegrationTest/PDO - - - - - ./src - - + + + ./src + + + + + ./test/CrateTest + + + ./test/CrateIntegrationTest/PDO + + diff --git a/src/Crate/PDO/PDO.php b/src/Crate/PDO/PDO.php index 34e30aa5..a6e62a07 100644 --- a/src/Crate/PDO/PDO.php +++ b/src/Crate/PDO/PDO.php @@ -33,6 +33,8 @@ class PDO extends BasePDO implements PDOInterface { + use PDOImplementation; + public const VERSION = '1.1.0'; public const DRIVER_NAME = 'crate'; @@ -247,7 +249,7 @@ public function exec($statement) /** * {@inheritDoc} */ - public function query($statement) + public function doQuery($statement) { $statement = $this->prepare($statement); $result = $statement->execute(); diff --git a/src/Crate/PDO/PDOImplementation.php b/src/Crate/PDO/PDOImplementation.php new file mode 100644 index 00000000..6c42a4cf --- /dev/null +++ b/src/Crate/PDO/PDOImplementation.php @@ -0,0 +1,49 @@ += 80000) { + class_alias('\Crate\PDO\PDOImplementationPhp8', '\Crate\PDO\PDOImplementation'); +} else { + class_alias('\Crate\PDO\PDOImplementationPhp7', '\Crate\PDO\PDOImplementation'); +} +// @codeCoverageIgnoreEnd diff --git a/src/Crate/PDO/PDOImplementationPhp7.php b/src/Crate/PDO/PDOImplementationPhp7.php new file mode 100644 index 00000000..2f6f128d --- /dev/null +++ b/src/Crate/PDO/PDOImplementationPhp7.php @@ -0,0 +1,47 @@ +doQuery(...func_get_args()); + } + + /** + * @param $statement + * @return PDOStatement + */ + abstract public function doQuery($statement); +} diff --git a/src/Crate/PDO/PDOImplementationPhp8.php b/src/Crate/PDO/PDOImplementationPhp8.php new file mode 100644 index 00000000..b26bbaf5 --- /dev/null +++ b/src/Crate/PDO/PDOImplementationPhp8.php @@ -0,0 +1,54 @@ +doQuery($query, $fetchMode, ...$fetchModeArgs); + return $this->doQuery($query); + } + + /** + * @param $statement + * @return PDOStatement + */ + abstract public function doQuery($statement); +} diff --git a/src/Crate/PDO/PDOInterface.php b/src/Crate/PDO/PDOInterface.php index d31e6e0c..66e4e935 100644 --- a/src/Crate/PDO/PDOInterface.php +++ b/src/Crate/PDO/PDOInterface.php @@ -20,10 +20,26 @@ * software solely pursuant to the terms of the relevant commercial agreement. */ +/* + * PDO compatibility for PHP 8.x. + * + * Reason: + * - https://github.com/php/php-src/pull/6220 + * + * Implementation derived and inspired from: + * - https://github.com/doctrine/dbal/pull/4347 + * - https://www.drupal.org/project/drupal/issues/3109885 + * - https://www.drupal.org/project/drupal/issues/3156881 + * - https://www.drupal.org/node/3170913 + * + */ + declare(strict_types=1); namespace Crate\PDO; +use const PHP_VERSION_ID; + /** * Interface PDOInterface * @@ -31,21 +47,10 @@ * * @internal */ -interface PDOInterface -{ - public function prepare($statement, $options = null); - public function beginTransaction(); - public function commit(); - public function rollback(); - public function inTransaction(); - public function exec($statement); - public function query($statement); - public function lastInsertId($name = null); - public function errorCode(); - public function errorInfo(); - public function setAttribute($attribute, $value); - public function getAttribute($attribute); - public function getServerVersion(); - public function getServerInfo(); - public static function getAvailableDrivers(); +// @codeCoverageIgnoreStart +if (PHP_VERSION_ID >= 80000) { + class_alias('\Crate\PDO\PDOInterfacePhp8', '\Crate\PDO\PDOInterface'); +} else { + class_alias('\Crate\PDO\PDOInterfacePhp7', '\Crate\PDO\PDOInterface'); } +// @codeCoverageIgnoreEnd diff --git a/src/Crate/PDO/PDOInterfacePhp7.php b/src/Crate/PDO/PDOInterfacePhp7.php new file mode 100644 index 00000000..7cc5735c --- /dev/null +++ b/src/Crate/PDO/PDOInterfacePhp7.php @@ -0,0 +1,44 @@ +hasExecuted()) { $this->execute(); @@ -533,7 +535,7 @@ public function getColumnMeta($column) /** * {@inheritDoc} */ - public function setFetchMode($mode, $params = null) + public function doSetFetchMode($mode, $params = null) { $args = func_get_args(); $argCount = count($args); @@ -612,7 +614,7 @@ public function debugDumpParams() /** * {@Inheritdoc} */ - public function getIterator() + public function getIterator(): \Iterator { $results = $this->fetchAll(); if ($results === false) { diff --git a/src/Crate/PDO/PDOStatementImplementation.php b/src/Crate/PDO/PDOStatementImplementation.php new file mode 100644 index 00000000..ddb4993e --- /dev/null +++ b/src/Crate/PDO/PDOStatementImplementation.php @@ -0,0 +1,47 @@ += 80000) { + class_alias('\Crate\PDO\PDOStatementImplementationPhp8', '\Crate\PDO\PDOStatementImplementation'); +} else { + class_alias('\Crate\PDO\PDOStatementImplementationPhp7', '\Crate\PDO\PDOStatementImplementation'); +} diff --git a/src/Crate/PDO/PDOStatementImplementationPhp7.php b/src/Crate/PDO/PDOStatementImplementationPhp7.php new file mode 100644 index 00000000..8413c4be --- /dev/null +++ b/src/Crate/PDO/PDOStatementImplementationPhp7.php @@ -0,0 +1,76 @@ +doSetFetchMode(...func_get_args()); + } + + /** + * @deprecated Use fetchAllNumeric(), fetchAllAssociative() or fetchFirstColumn() instead. + * + * @param int|null $fetchMode + * @param mixed $fetchArgument + * @param mixed $ctorArgs + * + * @return mixed[] + */ + public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null) + { + return $this->doFetchAll(...func_get_args()); + } + + /** + * @param int|null $mode + * @param int|string|object $params + * + * @return bool + */ + abstract public function doSetFetchMode($mode, $params = null); + + /** + * @param int|null $fetch_style + * @param int|string|object $fetch_argument + * @param mixed[] $ctor_args + * + * @return mixed[] + */ + abstract public function doFetchAll($fetch_style = null, $fetch_argument = null, $ctor_args = null); +} diff --git a/src/Crate/PDO/PDOStatementImplementationPhp8.php b/src/Crate/PDO/PDOStatementImplementationPhp8.php new file mode 100644 index 00000000..b1467bb2 --- /dev/null +++ b/src/Crate/PDO/PDOStatementImplementationPhp8.php @@ -0,0 +1,74 @@ +doSetFetchMode($mode, ...$args); + } + + /** + * @deprecated Use fetchAllNumeric(), fetchAllAssociative() or fetchFirstColumn() instead. + * + * @param int|null $mode + * @param mixed ...$args + * + * @return mixed[] + */ + public function fetchAll(int $mode = null, ...$args): mixed + { + return $this->doFetchAll($mode, ...$args); + } + + /** + * @param int|null $mode + * @param int|string|object $params + * + * @return bool + */ + abstract public function doSetFetchMode($mode, $params = null); + + /** + * @param int|null $fetch_style + * @param int|string|object $fetch_argument + * @param mixed[] $ctor_args + * + * @return mixed[] + */ + abstract public function doFetchAll($fetch_style = null, $fetch_argument = null, $ctor_args = null); +} diff --git a/test/CrateIntegrationTest/PDO/PDOTest.php b/test/CrateIntegrationTest/PDO/PDOTest.php index 0055730c..e2ac8784 100644 --- a/test/CrateIntegrationTest/PDO/PDOTest.php +++ b/test/CrateIntegrationTest/PDO/PDOTest.php @@ -70,6 +70,6 @@ public function testDeleteWithMultipleAffectedRows() public function testGetServerVersion() { $result = $this->pdo->getServerVersion(); - $this->assertRegExp("/[0-9]+\.[0-9]+\.[0-9]+/", $result); + $this->assertMatchesRegularExpression("/[0-9]+\.[0-9]+\.[0-9]+/", $result); } } diff --git a/test/CrateTest/PDO/Http/ServerPoolTest.php b/test/CrateTest/PDO/Http/ServerPoolTest.php index 85246aae..7ba6c228 100644 --- a/test/CrateTest/PDO/Http/ServerPoolTest.php +++ b/test/CrateTest/PDO/Http/ServerPoolTest.php @@ -202,7 +202,10 @@ public function testGuzzleClientOptionTest(array $options, array $expected) ->with('POST', '/_sql', $expectedWithDefaults) ->willReturn(new Response(200, [], $body)); - $this->serverPool->execute('query', []); + $result = $this->serverPool->execute('query', []); + + $this->assertEquals(new Collection([], [], 0, 0), $result); + } public function testExecuteWithNoRespondingServers() @@ -213,6 +216,8 @@ public function testExecuteWithNoRespondingServers() ->willThrowException(new ConnectException('helloWorld', new Request('post', 'localhost'))); $this->expectException(ConnectException::class); + $this->expectExceptionMessage("No more servers available, exception from last server: helloWorld"); + $this->serverPool->execute('helloWorld', []); } @@ -221,21 +226,22 @@ public function testExecuteWithFirstFailing() $body = json_encode(['rows' => [], 'cols' => [], 'duration' => 0, 'rowcount' => 0]); $this->client - ->expects($this->at(0)) + ->expects($this->exactly(2)) ->method('request') - ->willThrowException(new ConnectException('helloWorld', new Request('post', 'localhost'))); + ->will(self::onConsecutiveCalls( + self::throwException(new ConnectException('helloWorld', new Request('post', 'localhost'))), + new Response(200, [], $body) + )); - $this->client - ->expects($this->at(1)) - ->method('request') - ->willReturn(new Response(200, [], $body)); + $result = $this->serverPool->execute('helloWorld', []); - $this->assertInstanceOf(Collection::class, $this->serverPool->execute('helloWorld', [])); + $this->assertInstanceOf(Collection::class, $result); + $this->assertEquals(new Collection([], [], 0, 0), $result); } public function testWithBadRequest() { - $body = json_encode(['error' => ['code' => 1337, 'message' => 'invalid sql, u fool.']]); + $body = json_encode(['error' => ['code' => 1337, 'message' => 'Invalid SQL statement']]); $request = new Request('post', 'localhost'); $response = new Response(400, [], $body); @@ -246,6 +252,8 @@ public function testWithBadRequest() ->willThrowException(new BadResponseException('error', $request, $response)); $this->expectException(RuntimeException::class); + $this->expectExceptionMessage("Invalid SQL statement"); + $this->serverPool->execute('helloWorld', []); } } diff --git a/test/CrateTest/PDO/PDOStatementTest.php b/test/CrateTest/PDO/PDOStatementTest.php index bb6ee1d2..19b9a1d3 100644 --- a/test/CrateTest/PDO/PDOStatementTest.php +++ b/test/CrateTest/PDO/PDOStatementTest.php @@ -357,6 +357,7 @@ public function testRowCount() /** * @covers ::fetchColumn + * @covers \Crate\PDO\Exception\InvalidArgumentException */ public function testFetchColumnWithInvalidColumnNumberType() { @@ -413,6 +414,7 @@ public function testFetchColumn() /** * @covers ::fetchAll + * @covers ::doFetchAll */ public function testFetchAllWithFailedExecution() { @@ -423,6 +425,7 @@ public function testFetchAllWithFailedExecution() /** * @covers ::fetchAll + * @covers ::doFetchAll */ public function testFetchAllWithInvalidFetchStyle() { @@ -540,6 +543,7 @@ public function fetchAllStyleProvider() /** * @dataProvider fetchAllStyleProvider * @covers ::fetchAll + * @covers ::doFetchAll * * @param string $fetchStyle * @param array $expected @@ -561,6 +565,8 @@ public function testFetchAll($fetchStyle, array $expected) /** * @covers ::fetchAll + * @covers ::doFetchAll + * @covers \Crate\PDO\Exception\InvalidArgumentException */ public function testFetchAllWithFetchStyleFuncAndInvalidCallback() { @@ -572,6 +578,7 @@ public function testFetchAllWithFetchStyleFuncAndInvalidCallback() /** * @covers ::fetchAll + * @covers ::doFetchAll */ public function testFetchAllBothSameColumnTwice() { @@ -585,6 +592,7 @@ public function testFetchAllBothSameColumnTwice() /** * @covers ::fetchAll + * @covers ::doFetchAll */ public function testFetchAllWithFetchStyleFunc() { @@ -599,6 +607,8 @@ public function testFetchAllWithFetchStyleFunc() /** * @covers ::fetchAll + * @covers ::doFetchAll + * @covers \Crate\PDO\Exception\InvalidArgumentException */ public function testFetchAllWithFetchStyleColumnAndInvalidColumnIndexType() { @@ -610,6 +620,7 @@ public function testFetchAllWithFetchStyleColumnAndInvalidColumnIndexType() /** * @covers ::fetchAll + * @covers ::doFetchAll */ public function testFetchAllWithFetchStyleColumnAndInvalidColumnIndex() { @@ -732,6 +743,8 @@ public function testGetColumnMeta() /** * @covers ::setFetchMode + * @covers ::doSetFetchMode + * @covers \Crate\PDO\Exception\InvalidArgumentException */ public function testSetFetchModeWithColumnAndMissingColNo() { @@ -745,6 +758,8 @@ public function testSetFetchModeWithColumnAndMissingColNo() /** * @covers ::setFetchMode + * @covers ::doSetFetchMode + * @covers \Crate\PDO\Exception\InvalidArgumentException */ public function testSetFetchModeWithColumnAndInvalidColNo() { @@ -758,6 +773,7 @@ public function testSetFetchModeWithColumnAndInvalidColNo() /** * @covers ::setFetchMode + * @covers ::doSetFetchMode */ public function testSetFetchModeWithColumn() { @@ -787,6 +803,7 @@ public function fetchModeStyleProvider() /** * @covers ::setFetchMode + * @covers ::doSetFetchMode * @dataProvider fetchModeStyleProvider * * @param int $fetchStyle @@ -807,6 +824,7 @@ public function testSetFetchMode($fetchStyle) /** * @covers ::setFetchMode + * @covers ::doSetFetchMode */ public function testSetFetchModeWithInvalidFetchStyle() { @@ -816,6 +834,9 @@ public function testSetFetchModeWithInvalidFetchStyle() /** * @covers ::setFetchMode + * @covers ::doSetFetchMode + * @covers \Crate\PDO\Exception\InvalidArgumentException + * * @dataProvider fetchModeStyleProvider * * @param int $fetchStyle diff --git a/test/CrateTest/PDO/PDOTest.php b/test/CrateTest/PDO/PDOTest.php index 04578376..366d2d85 100644 --- a/test/CrateTest/PDO/PDOTest.php +++ b/test/CrateTest/PDO/PDOTest.php @@ -28,6 +28,7 @@ use Crate\PDO\Http\ServerInterface; use Crate\PDO\PDO; use Crate\PDO\PDOStatement; +use Generator; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; @@ -308,4 +309,38 @@ public function testLastInsertIdThrowsUnsupportedException() $this->expectException(UnsupportedException::class); $this->pdo->lastInsertId(); } + + /** + * PHP8 has a new PDO query interface. + * Not all things have been implemented yet. + * + * @requires PHP >= 8 + * @covers ::query + * + * @dataProvider fetchModeStyleProvider + * @param $fetchMode + */ + public function testNewPhp8PdoInterfaceQueryWithFetchMode($fetchMode) + { + $this->expectException(UnsupportedException::class); + $this->expectExceptionMessage('PDO::query $fetchMode not implemented yet'); + + $this->pdo->query("SELECT 1;", $fetchMode, 'foobar'); + } + + /** + * Provide test function with a list of parameters. + * + * @return Generator + */ + public function fetchModeStyleProvider() + { + return [ + [PDO::FETCH_ASSOC], + [PDO::FETCH_NUM], + [PDO::FETCH_BOTH], + [PDO::FETCH_BOUND], + [PDO::FETCH_NAMED], + ]; + } }