From 33e741beb49affeeb489930ef01dc38744a74df1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20Felix=20=C5=A0ulc?= Date: Fri, 26 Dec 2025 20:39:13 +0000 Subject: [PATCH 1/5] Align repository with Contributte standards - Upgrade to PHP 8.2+ and Nette 3.2+ - Replace ninjify/qa with contributte/qa v0.4 - Replace nette/tester with contributte/tester v0.3 - Replace phpstan/* with contributte/phpstan v0.2 - Split GitHub Actions into separate workflow files - Use Contributte reusable workflows for codesniffer/phpstan - Update Makefile to match Contributte template - Add native type hints to properties (PHP 8.0+) - Fix code style issues (method ordering, spacing) - Reorganize test directories to PascalCase - Update test bootstrap to use Contributte\Tester - Remove reference variables in closures (use stdClass) - Update ruleset.xml to use new array syntax --- .editorconfig | 2 +- .gitattributes | 6 +- .github/.kodiak.toml | 10 - .github/workflows/codesniffer.yml | 18 ++ .github/workflows/coverage.yml | 44 +++ .github/workflows/main.yaml | 293 ------------------ .github/workflows/phpstan.yml | 18 ++ .github/workflows/tests.yml | 144 +++++++++ .gitignore | 8 +- Makefile | 64 ++-- composer.json | 23 +- phpstan.neon | 17 +- ruleset.xml | 18 +- src/Transaction/Promise.php | 3 +- src/Transaction/Transaction.php | 24 +- tests/.coveralls.yml | 4 - tests/.gitignore | 10 - .../Unit}/Transaction/PromiseTest.phpt | 38 ++- .../Unit}/Transaction/TransactionTest.phpt | 0 .../Transaction/UnresolvedExceptionTest.phpt | 14 +- tests/{fixtures => Fixtures}/database.sql | 0 tests/{helpers => Helpers}/BaseTestCase.php | 6 +- .../{helpers => Helpers}/DatabaseFactory.php | 0 tests/bootstrap.php | 7 +- 24 files changed, 344 insertions(+), 427 deletions(-) delete mode 100644 .github/.kodiak.toml create mode 100644 .github/workflows/codesniffer.yml create mode 100644 .github/workflows/coverage.yml delete mode 100644 .github/workflows/main.yaml create mode 100644 .github/workflows/phpstan.yml create mode 100644 .github/workflows/tests.yml delete mode 100644 tests/.coveralls.yml delete mode 100644 tests/.gitignore rename tests/{cases/unit => Cases/Unit}/Transaction/PromiseTest.phpt (58%) rename tests/{cases/unit => Cases/Unit}/Transaction/TransactionTest.phpt (100%) rename tests/{cases/unit => Cases/Unit}/Transaction/UnresolvedExceptionTest.phpt (72%) rename tests/{fixtures => Fixtures}/database.sql (100%) rename tests/{helpers => Helpers}/BaseTestCase.php (91%) rename tests/{helpers => Helpers}/DatabaseFactory.php (100%) diff --git a/.editorconfig b/.editorconfig index 3faf149..5e5b915 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,6 +11,6 @@ indent_style = tab indent_size = tab tab_width = 4 -[{*.json, *.yaml, *.yml, *.md}] +[*.{json,yaml,yml,md}] indent_style = space indent_size = 2 diff --git a/.gitattributes b/.gitattributes index 12910b6..601a02f 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,11 +1,9 @@ -# Not archived .docs export-ignore -tests export-ignore .editorconfig export-ignore .gitattributes export-ignore .gitignore export-ignore -.travis.yml export-ignore Makefile export-ignore -phpstan.neon export-ignore README.md export-ignore +phpstan.neon export-ignore ruleset.xml export-ignore +tests export-ignore diff --git a/.github/.kodiak.toml b/.github/.kodiak.toml deleted file mode 100644 index 60c34b6..0000000 --- a/.github/.kodiak.toml +++ /dev/null @@ -1,10 +0,0 @@ -version = 1 - -[merge] -automerge_label = "automerge" -blacklist_title_regex = "^WIP.*" -blacklist_labels = ["WIP"] -method = "rebase" -delete_branch_on_merge = true -notify_on_conflict = true -optimistic_updates = false diff --git a/.github/workflows/codesniffer.yml b/.github/workflows/codesniffer.yml new file mode 100644 index 0000000..d5ff803 --- /dev/null +++ b/.github/workflows/codesniffer.yml @@ -0,0 +1,18 @@ +name: "Codesniffer" + +on: + pull_request: + workflow_dispatch: + + push: + branches: ["*"] + + schedule: + - cron: "0 8 * * 1" + +jobs: + codesniffer: + name: "Codesniffer" + uses: contributte/.github/.github/workflows/codesniffer.yml@master + with: + php: "8.3" diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 0000000..e8cf021 --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,44 @@ +name: "Coverage" + +on: + push: + branches: ["master"] + workflow_dispatch: + +jobs: + coverage: + name: "Code Coverage" + runs-on: ubuntu-latest + + services: + mysql: + image: mysql:8.0 + env: + MYSQL_ALLOW_EMPTY_PASSWORD: yes + MYSQL_DATABASE: mydb + ports: + - 3306:3306 + options: >- + --health-cmd "mysqladmin ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + steps: + - uses: actions/checkout@v4 + + - uses: shivammathur/setup-php@v2 + with: + php-version: "8.3" + extensions: pdo, pdo_mysql + coverage: pcov + + - run: composer update --no-interaction --no-progress + + - run: mysql -h 127.0.0.1 -u root mydb < tests/Fixtures/database.sql + + - run: make coverage + + - uses: codecov/codecov-action@v4 + with: + files: coverage.xml diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml deleted file mode 100644 index 4678489..0000000 --- a/.github/workflows/main.yaml +++ /dev/null @@ -1,293 +0,0 @@ -name: "build" - -on: - pull_request: - paths-ignore: - - ".docs/**" - push: - branches: - - "*" - schedule: - - cron: "0 8 * * 1" # At 08:00 on Monday - -env: - extensions: "json" - cache-version: "1" - composer-version: "v2" - composer-install: "composer update --no-interaction --no-progress --prefer-dist --prefer-stable" - -jobs: - qa: - name: "Quality assurance" - runs-on: "${{ matrix.operating-system }}" - - strategy: - matrix: - php-version: [ "7.4" ] - operating-system: [ "ubuntu-latest" ] - fail-fast: false - - steps: - - name: "Checkout" - uses: "actions/checkout@v2" - - - name: "Setup PHP cache environment" - id: "extcache" - uses: "shivammathur/cache-extensions@v1" - with: - php-version: "${{ matrix.php-version }}" - extensions: "${{ env.extensions }}" - key: "${{ env.cache-version }}" - - - name: "Cache PHP extensions" - uses: "actions/cache@v2" - with: - path: "${{ steps.extcache.outputs.dir }}" - key: "${{ steps.extcache.outputs.key }}" - restore-keys: "${{ steps.extcache.outputs.key }}" - - - name: "Install PHP" - uses: "shivammathur/setup-php@v2" - with: - php-version: "${{ matrix.php-version }}" - extensions: "${{ env.extensions }}" - tools: "composer:${{ env.composer-version }} " - - - name: "Setup problem matchers for PHP" - run: 'echo "::add-matcher::${{ runner.tool_cache }}/php.json"' - - - name: "Get Composer cache directory" - id: "composercache" - run: 'echo "::set-output name=dir::$(composer config cache-files-dir)"' - - - name: "Cache PHP dependencies" - uses: "actions/cache@v2" - with: - path: "${{ steps.composercache.outputs.dir }}" - key: "${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}" - restore-keys: "${{ runner.os }}-composer-" - - - name: "Validate Composer" - run: "composer validate" - - - name: "Install dependencies" - run: "${{ env.composer-install }}" - - - name: "Coding Standard" - run: "make cs" - - static-analysis: - name: "Static analysis" - runs-on: "${{ matrix.operating-system }}" - - strategy: - matrix: - php-version: [ "7.4" ] - operating-system: [ "ubuntu-latest" ] - fail-fast: false - - steps: - - name: "Checkout" - uses: "actions/checkout@v2" - - - name: "Setup PHP cache environment" - id: "extcache" - uses: "shivammathur/cache-extensions@v1" - with: - php-version: "${{ matrix.php-version }}" - extensions: "${{ env.extensions }}" - key: "${{ env.cache-version }}" - - - name: "Cache PHP extensions" - uses: "actions/cache@v2" - with: - path: "${{ steps.extcache.outputs.dir }}" - key: "${{ steps.extcache.outputs.key }}" - restore-keys: "${{ steps.extcache.outputs.key }}" - - - name: "Install PHP" - uses: "shivammathur/setup-php@v2" - with: - php-version: "${{ matrix.php-version }}" - extensions: "${{ env.extensions }}" - tools: "composer:${{ env.composer-version }} " - - - name: "Setup problem matchers for PHP" - run: 'echo "::add-matcher::${{ runner.tool_cache }}/php.json"' - - - name: "Get Composer cache directory" - id: "composercache" - run: 'echo "::set-output name=dir::$(composer config cache-files-dir)"' - - - name: "Cache PHP dependencies" - uses: "actions/cache@v2" - with: - path: "${{ steps.composercache.outputs.dir }}" - key: "${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}" - restore-keys: "${{ runner.os }}-composer-" - - - name: "Install dependencies" - run: "${{ env.composer-install }}" - - - name: "PHPStan" - run: "make phpstan" - - tests: - name: "Tests" - runs-on: "${{ matrix.operating-system }}" - - services: - mysql: - image: mysql:5.7 - env: - MYSQL_ALLOW_EMPTY_PASSWORD: yes - MYSQL_DATABASE: mydb - ports: - - 3306:3306 - - strategy: - matrix: - php-version: [ "7.2", "7.3", "7.4", "8.0" ] - operating-system: [ "ubuntu-latest" ] - composer-args: [ "" ] - include: - - php-version: "7.4" - operating-system: "ubuntu-latest" - composer-args: "--prefer-lowest" - - php-version: "8.0" - operating-system: "ubuntu-latest" - composer-args: "" - fail-fast: false - - continue-on-error: "${{ matrix.php-version == '8.0' }}" - - steps: - - name: "Checkout" - uses: "actions/checkout@v2" - - - name: "Setup PHP cache environment" - id: "extcache" - uses: "shivammathur/cache-extensions@v1" - with: - php-version: "${{ matrix.php-version }}" - extensions: "${{ env.extensions }}" - key: "${{ env.cache-version }}" - - - name: "Cache PHP extensions" - uses: "actions/cache@v2" - with: - path: "${{ steps.extcache.outputs.dir }}" - key: "${{ steps.extcache.outputs.key }}" - restore-keys: "${{ steps.extcache.outputs.key }}" - - - name: "Install PHP" - uses: "shivammathur/setup-php@v2" - with: - php-version: "${{ matrix.php-version }}" - extensions: "${{ env.extensions }}" - tools: "composer:${{ env.composer-version }} " - - - name: "Setup problem matchers for PHP" - run: 'echo "::add-matcher::${{ runner.tool_cache }}/php.json"' - - - name: "Get Composer cache directory" - id: "composercache" - run: 'echo "::set-output name=dir::$(composer config cache-files-dir)"' - - - name: "Cache PHP dependencies" - uses: "actions/cache@v2" - with: - path: "${{ steps.composercache.outputs.dir }}" - key: "${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}" - restore-keys: "${{ runner.os }}-composer-" - - - name: "Install dependencies" - run: "${{ env.composer-install }} ${{ matrix.composer-args }}" - - - name: "Setup problem matchers for PHPUnit" - run: 'echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"' - - - name: "Creating test database" - run: "mysql -h 127.0.0.1 -u root mydb < tests/fixtures/database.sql" - - - name: "Tests" - run: "make tests" - - tests-code-coverage: - name: "Tests with code coverage" - runs-on: "${{ matrix.operating-system }}" - - services: - mysql: - image: mysql:5.7 - env: - MYSQL_ALLOW_EMPTY_PASSWORD: yes - MYSQL_DATABASE: mydb - ports: - - 3306:3306 - - strategy: - matrix: - php-version: [ "7.4" ] - operating-system: [ "ubuntu-latest" ] - fail-fast: false - - if: "github.event_name == 'push'" - - steps: - - name: "Checkout" - uses: "actions/checkout@v2" - - - name: "Setup PHP cache environment" - id: "extcache" - uses: "shivammathur/cache-extensions@v1" - with: - php-version: "${{ matrix.php-version }}" - extensions: "${{ env.extensions }}" - key: "${{ env.cache-version }}" - - - name: "Cache PHP extensions" - uses: "actions/cache@v2" - with: - path: "${{ steps.extcache.outputs.dir }}" - key: "${{ steps.extcache.outputs.key }}" - restore-keys: "${{ steps.extcache.outputs.key }}" - - - name: "Install PHP" - uses: "shivammathur/setup-php@v2" - with: - php-version: "${{ matrix.php-version }}" - extensions: "${{ env.extensions }}" - tools: "composer:${{ env.composer-version }} " - - - name: "Setup problem matchers for PHP" - run: 'echo "::add-matcher::${{ runner.tool_cache }}/php.json"' - - - name: "Get Composer cache directory" - id: "composercache" - run: 'echo "::set-output name=dir::$(composer config cache-files-dir)"' - - - name: "Cache PHP dependencies" - uses: "actions/cache@v2" - with: - path: "${{ steps.composercache.outputs.dir }}" - key: "${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}" - restore-keys: "${{ runner.os }}-composer-" - - - name: "Install dependencies" - run: "${{ env.composer-install }}" - - - name: "Creating test database" - run: "mysql -h 127.0.0.1 -u root mydb < tests/fixtures/database.sql" - - - name: "Tests" - run: "make coverage-clover" - - - name: "Coveralls.io" - env: - CI_NAME: github - CI: true - COVERALLS_REPO_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - run: | - wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.1.0/php-coveralls.phar - php php-coveralls.phar --verbose --config tests/.coveralls.yml diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml new file mode 100644 index 0000000..c0dccb4 --- /dev/null +++ b/.github/workflows/phpstan.yml @@ -0,0 +1,18 @@ +name: "Phpstan" + +on: + pull_request: + workflow_dispatch: + + push: + branches: ["*"] + + schedule: + - cron: "0 10 * * 1" + +jobs: + phpstan: + name: "Phpstan" + uses: contributte/.github/.github/workflows/phpstan.yml@master + with: + php: "8.3" diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..4d846f3 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,144 @@ +name: "Tests" + +on: + pull_request: + workflow_dispatch: + + push: + branches: ["*"] + + schedule: + - cron: "0 10 * * 1" + +jobs: + test84: + name: "Tests on PHP 8.4" + runs-on: ubuntu-latest + + services: + mysql: + image: mysql:8.0 + env: + MYSQL_ALLOW_EMPTY_PASSWORD: yes + MYSQL_DATABASE: mydb + ports: + - 3306:3306 + options: >- + --health-cmd "mysqladmin ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + steps: + - uses: actions/checkout@v4 + + - uses: shivammathur/setup-php@v2 + with: + php-version: "8.4" + extensions: pdo, pdo_mysql + coverage: none + + - run: composer update --no-interaction --no-progress + + - run: mysql -h 127.0.0.1 -u root mydb < tests/Fixtures/database.sql + + - run: make tests + + test83: + name: "Tests on PHP 8.3" + runs-on: ubuntu-latest + + services: + mysql: + image: mysql:8.0 + env: + MYSQL_ALLOW_EMPTY_PASSWORD: yes + MYSQL_DATABASE: mydb + ports: + - 3306:3306 + options: >- + --health-cmd "mysqladmin ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + steps: + - uses: actions/checkout@v4 + + - uses: shivammathur/setup-php@v2 + with: + php-version: "8.3" + extensions: pdo, pdo_mysql + coverage: none + + - run: composer update --no-interaction --no-progress + + - run: mysql -h 127.0.0.1 -u root mydb < tests/Fixtures/database.sql + + - run: make tests + + test82: + name: "Tests on PHP 8.2" + runs-on: ubuntu-latest + + services: + mysql: + image: mysql:8.0 + env: + MYSQL_ALLOW_EMPTY_PASSWORD: yes + MYSQL_DATABASE: mydb + ports: + - 3306:3306 + options: >- + --health-cmd "mysqladmin ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + steps: + - uses: actions/checkout@v4 + + - uses: shivammathur/setup-php@v2 + with: + php-version: "8.2" + extensions: pdo, pdo_mysql + coverage: none + + - run: composer update --no-interaction --no-progress + + - run: mysql -h 127.0.0.1 -u root mydb < tests/Fixtures/database.sql + + - run: make tests + + lowest: + name: "Tests on lowest dependencies" + runs-on: ubuntu-latest + + services: + mysql: + image: mysql:8.0 + env: + MYSQL_ALLOW_EMPTY_PASSWORD: yes + MYSQL_DATABASE: mydb + ports: + - 3306:3306 + options: >- + --health-cmd "mysqladmin ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + steps: + - uses: actions/checkout@v4 + + - uses: shivammathur/setup-php@v2 + with: + php-version: "8.2" + extensions: pdo, pdo_mysql + coverage: none + + - run: composer update --no-interaction --no-progress --prefer-dist --prefer-stable --prefer-lowest + + - run: mysql -h 127.0.0.1 -u root mydb < tests/Fixtures/database.sql + + - run: make tests diff --git a/.gitignore b/.gitignore index b1b6f4d..f0b3670 100644 --- a/.gitignore +++ b/.gitignore @@ -6,5 +6,9 @@ /composer.lock # Tests -/temp -/coverage.xml +/tests/tmp +/coverage.* +/tests/**/*.log +/tests/**/*.html +/tests/**/*.expected +/tests/**/*.actual diff --git a/Makefile b/Makefile index 0b15037..33bc117 100644 --- a/Makefile +++ b/Makefile @@ -1,30 +1,34 @@ -.PHONY: qa lint cs csf phpstan tests coverage - -all: - @$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' | xargs - -vendor: composer.json composer.lock - composer install - -qa: lint phpstan cs - -lint: vendor - vendor/bin/linter src tests - -cs: vendor - vendor/bin/codesniffer src tests - -csf: vendor - vendor/bin/codefixer src tests - -phpstan: vendor - vendor/bin/phpstan analyse -c phpstan.neon src - -tests: vendor - vendor/bin/tester -s -p php --colors 1 -C tests/cases - -coverage-clover: - vendor/bin/tester -s -p phpdbg --colors 1 -C --coverage ./coverage.xml --coverage-src ./src tests/cases - -coverage-html: - vendor/bin/tester -s -p phpdbg --colors 1 -C --coverage ./coverage.html --coverage-src ./src tests/cases +.PHONY: install +install: + composer update + +.PHONY: qa +qa: phpstan cs + +.PHONY: cs +cs: +ifdef GITHUB_ACTION + vendor/bin/phpcs --standard=ruleset.xml --encoding=utf-8 --extensions="php,phpt" --colors -nsp -q --report=checkstyle src tests | cs2pr +else + vendor/bin/phpcs --standard=ruleset.xml --encoding=utf-8 --extensions="php,phpt" --colors -nsp src tests +endif + +.PHONY: csf +csf: + vendor/bin/phpcbf --standard=ruleset.xml --encoding=utf-8 --extensions="php,phpt" --colors -nsp src tests + +.PHONY: phpstan +phpstan: + vendor/bin/phpstan analyse -c phpstan.neon + +.PHONY: tests +tests: + vendor/bin/tester -s -p php --colors 1 -C tests/Cases + +.PHONY: coverage +coverage: +ifdef GITHUB_ACTION + vendor/bin/tester -s -p phpdbg --colors 1 -C --coverage coverage.xml --coverage-src src tests/Cases +else + vendor/bin/tester -s -p phpdbg --colors 1 -C --coverage coverage.html --coverage-src src tests/Cases +endif diff --git a/composer.json b/composer.json index 32211dc..e27bc5c 100644 --- a/composer.json +++ b/composer.json @@ -17,21 +17,17 @@ } ], "require": { - "php": ">=7.2", - "nette/database": "^3.0.2" + "php": ">=8.2", + "nette/database": "^3.2" }, "require-dev": { - "nette/tester": "~2.3.2", - "ninjify/qa": "^0.13", - "ninjify/nunjuck": "^0.3.0", - "nette/di": "^3.0.1", - "phpstan/phpstan": "^1.0.0", - "phpstan/phpstan-deprecation-rules": "^1.0.0", - "phpstan/phpstan-nette": "^1.0.0", - "phpstan/phpstan-strict-rules": "^1.0.0" + "contributte/phpstan": "^0.2.0", + "contributte/qa": "^0.4.0", + "contributte/tester": "^0.3.0", + "nette/di": "^3.2" }, "suggest": { - "nette/di": "to use TransactionExtesion [CompilerExtension]" + "nette/di": "to use TransactionExtension [CompilerExtension]" }, "autoload": { "psr-4": { @@ -40,8 +36,7 @@ }, "autoload-dev": { "psr-4": { - "Tests\\Cases\\Unit\\": "tests/cases/unit", - "Tests\\Helpers\\": "tests/helpers" + "Tests\\": "tests" } }, "minimum-stability": "dev", @@ -54,7 +49,7 @@ }, "extra": { "branch-alias": { - "dev-master": "0.4.x-dev" + "dev-master": "0.5.x-dev" } } } diff --git a/phpstan.neon b/phpstan.neon index cdb7165..cd64186 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,9 +1,16 @@ includes: - - vendor/phpstan/phpstan-deprecation-rules/rules.neon - - vendor/phpstan/phpstan-nette/extension.neon - - vendor/phpstan/phpstan-nette/rules.neon - - vendor/phpstan/phpstan-strict-rules/rules.neon + - vendor/contributte/phpstan/phpstan.neon parameters: level: 9 - phpVersion: 70200 + phpVersion: 80200 + + scanDirectories: + - src + + fileExtensions: + - php + + paths: + - src + - .docs diff --git a/ruleset.xml b/ruleset.xml index a853f35..924b8ac 100644 --- a/ruleset.xml +++ b/ruleset.xml @@ -1,19 +1,19 @@ - - - + - - + + + + + + + + diff --git a/src/Transaction/Promise.php b/src/Transaction/Promise.php index 0254878..7f4cd68 100644 --- a/src/Transaction/Promise.php +++ b/src/Transaction/Promise.php @@ -7,8 +7,7 @@ class Promise { - /** @var Transaction */ - private $transaction; + private Transaction $transaction; public function __construct(Transaction $transaction) { diff --git a/src/Transaction/Transaction.php b/src/Transaction/Transaction.php index 1221992..4e3f6ee 100644 --- a/src/Transaction/Transaction.php +++ b/src/Transaction/Transaction.php @@ -13,19 +13,16 @@ class Transaction { /** @var callable[] */ - public $onUnresolved = []; + public array $onUnresolved = []; /** @var string[] */ - protected static $drivers = ['pgsql', 'mysql', 'mysqli', 'sqlite']; + protected static array $drivers = ['pgsql', 'mysql', 'mysqli', 'sqlite']; - /** @var int */ - protected static $level = 0; + protected static int $level = 0; - /** @var UnresolvedTransactionException */ - protected $unresolved; + protected UnresolvedTransactionException $unresolved; - /** @var Connection */ - protected $connection; + protected Connection $connection; public function __construct(Connection $connection) { @@ -45,11 +42,6 @@ public function __destruct() } } - protected function isSupported(): bool - { - return in_array($this->connection->getPdo()->getAttribute(PDO::ATTR_DRIVER_NAME), self::$drivers, true); - } - public function getConnection(): Connection { return $this->connection; @@ -72,6 +64,7 @@ public function transaction(callable $callback): void $this->commit(); } catch (Throwable $e) { $this->rollback(); + throw $e; } } @@ -144,4 +137,9 @@ public function promise(): Promise return new Promise($this); } + protected function isSupported(): bool + { + return in_array($this->connection->getPdo()->getAttribute(PDO::ATTR_DRIVER_NAME), self::$drivers, true); + } + } diff --git a/tests/.coveralls.yml b/tests/.coveralls.yml deleted file mode 100644 index 82764a3..0000000 --- a/tests/.coveralls.yml +++ /dev/null @@ -1,4 +0,0 @@ -# for php-coveralls -service_name: travis-ci -coverage_clover: coverage.xml -json_path: coverage.json diff --git a/tests/.gitignore b/tests/.gitignore deleted file mode 100644 index f0d3402..0000000 --- a/tests/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -# Folders - recursive -*.expected -*.actual - -# Folders -/tmp - -# Files -/*.log -/*.html diff --git a/tests/cases/unit/Transaction/PromiseTest.phpt b/tests/Cases/Unit/Transaction/PromiseTest.phpt similarity index 58% rename from tests/cases/unit/Transaction/PromiseTest.phpt rename to tests/Cases/Unit/Transaction/PromiseTest.phpt index 725fb84..5ec83a4 100644 --- a/tests/cases/unit/Transaction/PromiseTest.phpt +++ b/tests/Cases/Unit/Transaction/PromiseTest.phpt @@ -8,6 +8,7 @@ namespace Tests\Cases\Unit\Transaction; +use stdClass; use Tester\Assert; use Tests\Helpers\BaseTestCase; @@ -21,14 +22,17 @@ final class PromiseTest extends BaseTestCase */ public function testPromiseFulfilled(): void { + $context = new stdClass(); + $context->fulfilled = false; + $this->transaction->promise()->then( - function () use (&$fulfilled): void { + function () use ($context): void { $this->table()->insert(['text' => time()]); - $fulfilled = true; + $context->fulfilled = true; } ); - Assert::true($fulfilled); + Assert::true($context->fulfilled); } /** @@ -36,20 +40,22 @@ final class PromiseTest extends BaseTestCase */ public function testPromiseCompleted(): void { - $success = null; + $context = new stdClass(); + $context->success = null; + $this->transaction->promise()->then( function (): void { $this->table()->insert(['text' => time()]); }, - function () use (&$success): void { - $success = true; + function () use ($context): void { + $context->success = true; }, - function () use (&$success): void { - $success = false; + function () use ($context): void { + $context->success = false; } ); - Assert::true($success); + Assert::true($context->success); } /** @@ -57,20 +63,22 @@ final class PromiseTest extends BaseTestCase */ public function testPromiseRejected(): void { - $rejected = null; + $context = new stdClass(); + $context->rejected = null; + $this->transaction->promise()->then( function (): void { $this->table()->insert([time() => time()]); }, - function () use (&$rejected): void { - $rejected = true; + function () use ($context): void { + $context->rejected = true; }, - function () use (&$rejected): void { - $rejected = false; + function () use ($context): void { + $context->rejected = false; } ); - Assert::false($rejected); + Assert::false($context->rejected); } } diff --git a/tests/cases/unit/Transaction/TransactionTest.phpt b/tests/Cases/Unit/Transaction/TransactionTest.phpt similarity index 100% rename from tests/cases/unit/Transaction/TransactionTest.phpt rename to tests/Cases/Unit/Transaction/TransactionTest.phpt diff --git a/tests/cases/unit/Transaction/UnresolvedExceptionTest.phpt b/tests/Cases/Unit/Transaction/UnresolvedExceptionTest.phpt similarity index 72% rename from tests/cases/unit/Transaction/UnresolvedExceptionTest.phpt rename to tests/Cases/Unit/Transaction/UnresolvedExceptionTest.phpt index 647702e..054102a 100644 --- a/tests/cases/unit/Transaction/UnresolvedExceptionTest.phpt +++ b/tests/Cases/Unit/Transaction/UnresolvedExceptionTest.phpt @@ -9,6 +9,7 @@ namespace Tests\Cases\Unit\Transaction; use Contributte\Database\Exception\UnresolvedTransactionException; +use stdClass; use Tester\Assert; use Tests\Helpers\BaseTestCase; @@ -22,10 +23,11 @@ final class UnresolvedExceptionTest extends BaseTestCase */ public function testThrows(): void { - /** @var UnresolvedTransactionException $exception */ - $exception = null; - $this->transaction->onUnresolved[] = function (UnresolvedTransactionException $e) use (&$exception): void { - $exception = $e; + $context = new stdClass(); + $context->exception = null; + + $this->transaction->onUnresolved[] = function (UnresolvedTransactionException $e) use ($context): void { + $context->exception = $e; }; // Begin transaction @@ -35,8 +37,8 @@ final class UnresolvedExceptionTest extends BaseTestCase // Remove reference $this->transaction = null; - Assert::notEqual(null, $exception); - Assert::type(UnresolvedTransactionException::class, $exception); + Assert::notEqual(null, $context->exception); + Assert::type(UnresolvedTransactionException::class, $context->exception); } } diff --git a/tests/fixtures/database.sql b/tests/Fixtures/database.sql similarity index 100% rename from tests/fixtures/database.sql rename to tests/Fixtures/database.sql diff --git a/tests/helpers/BaseTestCase.php b/tests/Helpers/BaseTestCase.php similarity index 91% rename from tests/helpers/BaseTestCase.php rename to tests/Helpers/BaseTestCase.php index 15ee161..1a9b932 100644 --- a/tests/helpers/BaseTestCase.php +++ b/tests/Helpers/BaseTestCase.php @@ -13,11 +13,9 @@ abstract class BaseTestCase extends TestCase { - /** @var Context */ - protected $db; + protected Context $db; - /** @var Transaction */ - protected $transaction; + protected ?Transaction $transaction = null; /** * Called before test method diff --git a/tests/helpers/DatabaseFactory.php b/tests/Helpers/DatabaseFactory.php similarity index 100% rename from tests/helpers/DatabaseFactory.php rename to tests/Helpers/DatabaseFactory.php diff --git a/tests/bootstrap.php b/tests/bootstrap.php index f9ee4bc..86c92a0 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,13 +1,10 @@ Date: Sun, 28 Dec 2025 12:16:51 +0000 Subject: [PATCH 2/5] CI: Add PHP 8.5, set default PHP to 8.4 - Add PHP 8.5 to test matrix - Change default PHP version from 8.3 to 8.4 for codesniffer, phpstan, and coverage --- .github/workflows/codesniffer.yml | 2 +- .github/workflows/coverage.yml | 2 +- .github/workflows/phpstan.yml | 2 +- .github/workflows/tests.yml | 33 +++++++++++++++++++++++++++++++ 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codesniffer.yml b/.github/workflows/codesniffer.yml index d5ff803..590394f 100644 --- a/.github/workflows/codesniffer.yml +++ b/.github/workflows/codesniffer.yml @@ -15,4 +15,4 @@ jobs: name: "Codesniffer" uses: contributte/.github/.github/workflows/codesniffer.yml@master with: - php: "8.3" + php: "8.4" diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index e8cf021..1649253 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -29,7 +29,7 @@ jobs: - uses: shivammathur/setup-php@v2 with: - php-version: "8.3" + php-version: "8.4" extensions: pdo, pdo_mysql coverage: pcov diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index c0dccb4..cd37eba 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -15,4 +15,4 @@ jobs: name: "Phpstan" uses: contributte/.github/.github/workflows/phpstan.yml@master with: - php: "8.3" + php: "8.4" diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4d846f3..8469aa4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -11,6 +11,39 @@ on: - cron: "0 10 * * 1" jobs: + test85: + name: "Tests on PHP 8.5" + runs-on: ubuntu-latest + + services: + mysql: + image: mysql:8.0 + env: + MYSQL_ALLOW_EMPTY_PASSWORD: yes + MYSQL_DATABASE: mydb + ports: + - 3306:3306 + options: >- + --health-cmd "mysqladmin ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + steps: + - uses: actions/checkout@v4 + + - uses: shivammathur/setup-php@v2 + with: + php-version: "8.5" + extensions: pdo, pdo_mysql + coverage: none + + - run: composer update --no-interaction --no-progress + + - run: mysql -h 127.0.0.1 -u root mydb < tests/Fixtures/database.sql + + - run: make tests + test84: name: "Tests on PHP 8.4" runs-on: ubuntu-latest From c31063405c957573ab55933f1a3ed59daa2deaab Mon Sep 17 00:00:00 2001 From: AI Date: Mon, 29 Dec 2025 16:21:59 +0000 Subject: [PATCH 3/5] Composer: use full version format (X.Y.Z) --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index e27bc5c..2316646 100644 --- a/composer.json +++ b/composer.json @@ -18,13 +18,13 @@ ], "require": { "php": ">=8.2", - "nette/database": "^3.2" + "nette/database": "^3.2.0" }, "require-dev": { "contributte/phpstan": "^0.2.0", "contributte/qa": "^0.4.0", "contributte/tester": "^0.3.0", - "nette/di": "^3.2" + "nette/di": "^3.2.0" }, "suggest": { "nette/di": "to use TransactionExtension [CompilerExtension]" From bf8eceeecd38ccb21a6562756195ad967cb50441 Mon Sep 17 00:00:00 2001 From: Contributte AI Date: Mon, 29 Dec 2025 16:43:11 +0000 Subject: [PATCH 4/5] Tests: use Environment::getTestDir() from contributte/tester --- tests/Helpers/BaseTestCase.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Helpers/BaseTestCase.php b/tests/Helpers/BaseTestCase.php index 1a9b932..1069817 100644 --- a/tests/Helpers/BaseTestCase.php +++ b/tests/Helpers/BaseTestCase.php @@ -3,11 +3,11 @@ namespace Tests\Helpers; use Contributte\Database\Transaction\Transaction; +use Contributte\Tester\Environment; use Nette\Database\Context; use Nette\Database\SqlLiteral; use Nette\Database\Table\Selection; use Tester\Assert; -use Tester\Environment; use Tester\TestCase; abstract class BaseTestCase extends TestCase @@ -22,7 +22,7 @@ abstract class BaseTestCase extends TestCase */ protected function setUp(): void { - Environment::lock('database', TMP_DIR); + \Tester\Environment::lock('database', Environment::getTestDir()); $this->db = DatabaseFactory::create(); $this->transaction = new Transaction($this->db->getConnection()); } From 4fd56284e7d927311bf5823298e752b6f52a60f4 Mon Sep 17 00:00:00 2001 From: Contributte AI Date: Mon, 29 Dec 2025 16:57:19 +0000 Subject: [PATCH 5/5] Tests: run sequentially to avoid database race conditions --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 33bc117..cf07265 100644 --- a/Makefile +++ b/Makefile @@ -23,12 +23,12 @@ phpstan: .PHONY: tests tests: - vendor/bin/tester -s -p php --colors 1 -C tests/Cases + vendor/bin/tester -s -p php --colors 1 -C -j 1 tests/Cases .PHONY: coverage coverage: ifdef GITHUB_ACTION - vendor/bin/tester -s -p phpdbg --colors 1 -C --coverage coverage.xml --coverage-src src tests/Cases + vendor/bin/tester -s -p phpdbg --colors 1 -C -j 1 --coverage coverage.xml --coverage-src src tests/Cases else - vendor/bin/tester -s -p phpdbg --colors 1 -C --coverage coverage.html --coverage-src src tests/Cases + vendor/bin/tester -s -p phpdbg --colors 1 -C -j 1 --coverage coverage.html --coverage-src src tests/Cases endif