diff --git a/.github/workflows/test-deploy.yml b/.github/workflows/test-deploy.yml
index 6e7f0d0..8dfe986 100644
--- a/.github/workflows/test-deploy.yml
+++ b/.github/workflows/test-deploy.yml
@@ -11,14 +11,19 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: 8.4
+
+ - uses: actions/checkout@v4
- name: Validate composer.json and composer.lock
run: composer validate
- name: Cache Composer packages
id: composer-cache
- uses: actions/cache@v2
+ uses: actions/cache@v4
with:
path: vendor
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
@@ -38,7 +43,7 @@ jobs:
run: vendor/bin/phpunit --testdox --color=always
- name: Mutation tests
- run: vendor/bin/infection --threads=2 --min-msi=100 --ansi && cat var/log/infection.log
+ run: vendor/bin/infection --threads=2 --min-msi=100 --ansi
- name: Mutation Report
run: cat var/log/infection.log
diff --git a/.gitignore b/.gitignore
index 5c2fee4..d291940 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
.phpunit.result.cache
+.phpunit.cache
config/.phpcs-cache
config/.phpunit.result.cache
.idea/
diff --git a/composer.json b/composer.json
index 2d816fc..f2efb17 100644
--- a/composer.json
+++ b/composer.json
@@ -10,16 +10,17 @@
}
],
"require": {
- "php": ">=8.1",
+ "php": ">=8.4",
"ext-json": "*",
- "ext-pdo": "*"
+ "ext-pdo": "*",
+ "tcds-io/php-better-generics": "dev-main"
},
"require-dev": {
- "infection/infection": "^0.26.19",
- "phpstan/phpstan": "^1.10",
- "phpunit/phpunit": "^9.5",
- "slevomat/coding-standard": "^8.9",
- "symfony/var-dumper": "^5.2"
+ "infection/infection": "^0.29",
+ "phpstan/phpstan": "^2.1",
+ "phpunit/phpunit": "^12.1",
+ "squizlabs/php_codesniffer": "^3.0",
+ "symfony/var-dumper": "^7.2"
},
"autoload": {
"psr-4": {
@@ -28,20 +29,20 @@
},
"autoload-dev": {
"psr-4": {
- "Test\\Tcds\\Io\\Orm\\": "tests/"
+ "Test\\Tcds\\Io\\Orm\\": "tests"
}
},
"scripts": {
- "cs:check": "vendor/bin/phpcs --colors -ps",
+ "cs:check": "vendor/bin/phpcs -s --colors --runtime-set testVersion 8.4",
"cs:fix": "vendor/bin/phpcbf --colors -ps",
- "mutation": "vendor/bin/infection --threads=2 --min-msi=100 --ansi",
+ "test:mutation": "vendor/bin/infection --threads=2 --min-msi=100 --ansi",
"test:stan": "php -d memory_limit=-1 vendor/bin/phpstan analyse src --level=max --ansi",
"test:unit": "vendor/bin/phpunit --testdox --color=always",
"tests": [
"@cs:check",
"@test:stan",
"@test:unit",
- "@mutation"
+ "@test:mutation"
]
},
"config": {
diff --git a/composer.lock b/composer.lock
index 5ac3ada..dc35865 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,38 +4,85 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "c6e053e38468460998443a9b54ca09f6",
- "packages": [],
+ "content-hash": "b8511f52080ee9ab941d02ca33f14477",
+ "packages": [
+ {
+ "name": "tcds-io/php-better-generics",
+ "version": "dev-main",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/tcds-io/php-better-generics.git",
+ "reference": "c93056f012a9b8538a1b6cb8351d863982e814a0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/tcds-io/php-better-generics/zipball/c93056f012a9b8538a1b6cb8351d863982e814a0",
+ "reference": "c93056f012a9b8538a1b6cb8351d863982e814a0",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^8.4"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "^2.1",
+ "phpunit/phpunit": "^10.5",
+ "slevomat/coding-standard": "^8.15"
+ },
+ "default-branch": true,
+ "type": "library",
+ "autoload": {
+ "files": [
+ "src/functional/functions.php"
+ ],
+ "psr-4": {
+ "Tcds\\Io\\Generic\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Thiago Cordeiro",
+ "email": "source@tcds.io"
+ }
+ ],
+ "description": "PHP library to better work with generics",
+ "support": {
+ "issues": "https://github.com/tcds-io/php-better-generics/issues",
+ "source": "https://github.com/tcds-io/php-better-generics/tree/main"
+ },
+ "time": "2025-05-12T19:14:59+00:00"
+ }
+ ],
"packages-dev": [
{
"name": "colinodell/json5",
- "version": "v2.3.0",
+ "version": "v3.0.0",
"source": {
"type": "git",
"url": "https://github.com/colinodell/json5.git",
- "reference": "15b063f8cb5e6deb15f0cd39123264ec0d19c710"
+ "reference": "5724d21bc5c910c2560af1b8915f0cc0163579c8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/colinodell/json5/zipball/15b063f8cb5e6deb15f0cd39123264ec0d19c710",
- "reference": "15b063f8cb5e6deb15f0cd39123264ec0d19c710",
+ "url": "https://api.github.com/repos/colinodell/json5/zipball/5724d21bc5c910c2560af1b8915f0cc0163579c8",
+ "reference": "5724d21bc5c910c2560af1b8915f0cc0163579c8",
"shasum": ""
},
"require": {
"ext-json": "*",
"ext-mbstring": "*",
- "php": "^7.1.3|^8.0"
- },
- "conflict": {
- "scrutinizer/ocular": "1.7.*"
+ "php": "^8.0"
},
"require-dev": {
- "mikehaertl/php-shellcommand": "^1.2.5",
- "phpstan/phpstan": "^1.4",
- "scrutinizer/ocular": "^1.6",
- "squizlabs/php_codesniffer": "^2.3 || ^3.0",
- "symfony/finder": "^4.4|^5.4|^6.0",
- "symfony/phpunit-bridge": "^5.4|^6.0"
+ "mikehaertl/php-shellcommand": "^1.7.0",
+ "phpstan/phpstan": "^1.10.57",
+ "scrutinizer/ocular": "^1.9",
+ "squizlabs/php_codesniffer": "^3.8.1",
+ "symfony/finder": "^6.0|^7.0",
+ "symfony/phpunit-bridge": "^7.0.3"
},
"bin": [
"bin/json5"
@@ -43,7 +90,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "3.0-dev"
+ "dev-main": "4.0-dev"
}
},
"autoload": {
@@ -76,7 +123,7 @@
],
"support": {
"issues": "https://github.com/colinodell/json5/issues",
- "source": "https://github.com/colinodell/json5/tree/v2.3.0"
+ "source": "https://github.com/colinodell/json5/tree/v3.0.0"
},
"funding": [
{
@@ -96,32 +143,40 @@
"type": "patreon"
}
],
- "time": "2022-12-27T16:44:40+00:00"
+ "time": "2024-02-09T13:06:12+00:00"
},
{
"name": "composer/pcre",
- "version": "3.1.0",
+ "version": "3.3.2",
"source": {
"type": "git",
"url": "https://github.com/composer/pcre.git",
- "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2"
+ "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2",
- "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2",
+ "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e",
+ "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e",
"shasum": ""
},
"require": {
"php": "^7.4 || ^8.0"
},
+ "conflict": {
+ "phpstan/phpstan": "<1.11.10"
+ },
"require-dev": {
- "phpstan/phpstan": "^1.3",
- "phpstan/phpstan-strict-rules": "^1.1",
- "symfony/phpunit-bridge": "^5"
+ "phpstan/phpstan": "^1.12 || ^2",
+ "phpstan/phpstan-strict-rules": "^1 || ^2",
+ "phpunit/phpunit": "^8 || ^9"
},
"type": "library",
"extra": {
+ "phpstan": {
+ "includes": [
+ "extension.neon"
+ ]
+ },
"branch-alias": {
"dev-main": "3.x-dev"
}
@@ -151,7 +206,7 @@
],
"support": {
"issues": "https://github.com/composer/pcre/issues",
- "source": "https://github.com/composer/pcre/tree/3.1.0"
+ "source": "https://github.com/composer/pcre/tree/3.3.2"
},
"funding": [
{
@@ -167,20 +222,20 @@
"type": "tidelift"
}
],
- "time": "2022-11-17T09:50:14+00:00"
+ "time": "2024-11-12T16:29:46+00:00"
},
{
"name": "composer/xdebug-handler",
- "version": "3.0.3",
+ "version": "3.0.5",
"source": {
"type": "git",
"url": "https://github.com/composer/xdebug-handler.git",
- "reference": "ced299686f41dce890debac69273b47ffe98a40c"
+ "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c",
- "reference": "ced299686f41dce890debac69273b47ffe98a40c",
+ "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef",
+ "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef",
"shasum": ""
},
"require": {
@@ -191,7 +246,7 @@
"require-dev": {
"phpstan/phpstan": "^1.0",
"phpstan/phpstan-strict-rules": "^1.1",
- "symfony/phpunit-bridge": "^6.0"
+ "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5"
},
"type": "library",
"autoload": {
@@ -215,9 +270,9 @@
"performance"
],
"support": {
- "irc": "irc://irc.freenode.org/composer",
+ "irc": "ircs://irc.libera.chat:6697/composer",
"issues": "https://github.com/composer/xdebug-handler/issues",
- "source": "https://github.com/composer/xdebug-handler/tree/3.0.3"
+ "source": "https://github.com/composer/xdebug-handler/tree/3.0.5"
},
"funding": [
{
@@ -233,165 +288,20 @@
"type": "tidelift"
}
],
- "time": "2022-02-25T21:32:43+00:00"
- },
- {
- "name": "dealerdirect/phpcodesniffer-composer-installer",
- "version": "v0.7.2",
- "source": {
- "type": "git",
- "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git",
- "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db",
- "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db",
- "shasum": ""
- },
- "require": {
- "composer-plugin-api": "^1.0 || ^2.0",
- "php": ">=5.3",
- "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0"
- },
- "require-dev": {
- "composer/composer": "*",
- "php-parallel-lint/php-parallel-lint": "^1.3.1",
- "phpcompatibility/php-compatibility": "^9.0"
- },
- "type": "composer-plugin",
- "extra": {
- "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin"
- },
- "autoload": {
- "psr-4": {
- "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Franck Nijhof",
- "email": "franck.nijhof@dealerdirect.com",
- "homepage": "http://www.frenck.nl",
- "role": "Developer / IT Manager"
- },
- {
- "name": "Contributors",
- "homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors"
- }
- ],
- "description": "PHP_CodeSniffer Standards Composer Installer Plugin",
- "homepage": "http://www.dealerdirect.com",
- "keywords": [
- "PHPCodeSniffer",
- "PHP_CodeSniffer",
- "code quality",
- "codesniffer",
- "composer",
- "installer",
- "phpcbf",
- "phpcs",
- "plugin",
- "qa",
- "quality",
- "standard",
- "standards",
- "style guide",
- "stylecheck",
- "tests"
- ],
- "support": {
- "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues",
- "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer"
- },
- "time": "2022-02-04T12:51:07+00:00"
- },
- {
- "name": "doctrine/instantiator",
- "version": "2.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/doctrine/instantiator.git",
- "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0",
- "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0",
- "shasum": ""
- },
- "require": {
- "php": "^8.1"
- },
- "require-dev": {
- "doctrine/coding-standard": "^11",
- "ext-pdo": "*",
- "ext-phar": "*",
- "phpbench/phpbench": "^1.2",
- "phpstan/phpstan": "^1.9.4",
- "phpstan/phpstan-phpunit": "^1.3",
- "phpunit/phpunit": "^9.5.27",
- "vimeo/psalm": "^5.4"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Marco Pivetta",
- "email": "ocramius@gmail.com",
- "homepage": "https://ocramius.github.io/"
- }
- ],
- "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
- "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
- "keywords": [
- "constructor",
- "instantiate"
- ],
- "support": {
- "issues": "https://github.com/doctrine/instantiator/issues",
- "source": "https://github.com/doctrine/instantiator/tree/2.0.0"
- },
- "funding": [
- {
- "url": "https://www.doctrine-project.org/sponsorship.html",
- "type": "custom"
- },
- {
- "url": "https://www.patreon.com/phpdoctrine",
- "type": "patreon"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
- "type": "tidelift"
- }
- ],
- "time": "2022-12-30T00:23:10+00:00"
+ "time": "2024-05-06T16:37:16+00:00"
},
{
"name": "fidry/cpu-core-counter",
- "version": "0.4.1",
+ "version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/theofidry/cpu-core-counter.git",
- "reference": "79261cc280aded96d098e1b0e0ba0c4881b432c2"
+ "reference": "8520451a140d3f46ac33042715115e290cf5785f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/79261cc280aded96d098e1b0e0ba0c4881b432c2",
- "reference": "79261cc280aded96d098e1b0e0ba0c4881b432c2",
+ "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f",
+ "reference": "8520451a140d3f46ac33042715115e290cf5785f",
"shasum": ""
},
"require": {
@@ -399,13 +309,13 @@
},
"require-dev": {
"fidry/makefile": "^0.2.0",
+ "fidry/php-cs-fixer-config": "^1.1.2",
"phpstan/extension-installer": "^1.2.0",
"phpstan/phpstan": "^1.9.2",
"phpstan/phpstan-deprecation-rules": "^1.0.0",
"phpstan/phpstan-phpunit": "^1.2.2",
"phpstan/phpstan-strict-rules": "^1.4.4",
- "phpunit/phpunit": "^9.5.26 || ^8.5.31",
- "theofidry/php-cs-fixer-config": "^1.0",
+ "phpunit/phpunit": "^8.5.31 || ^9.5.26",
"webmozarts/strict-phpunit": "^7.5"
},
"type": "library",
@@ -431,7 +341,7 @@
],
"support": {
"issues": "https://github.com/theofidry/cpu-core-counter/issues",
- "source": "https://github.com/theofidry/cpu-core-counter/tree/0.4.1"
+ "source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0"
},
"funding": [
{
@@ -439,7 +349,7 @@
"type": "github"
}
],
- "time": "2022-12-16T22:01:02+00:00"
+ "time": "2024-08-06T10:04:20+00:00"
},
{
"name": "infection/abstract-testframework-adapter",
@@ -620,63 +530,63 @@
},
{
"name": "infection/infection",
- "version": "0.26.19",
+ "version": "0.29.14",
"source": {
"type": "git",
"url": "https://github.com/infection/infection.git",
- "reference": "bd7351c88f3a797ea8977e68fe6a3f4d4c5f457f"
+ "reference": "feea2a48a8aeedd3a4d2105167b41a46f0e568a3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/infection/infection/zipball/bd7351c88f3a797ea8977e68fe6a3f4d4c5f457f",
- "reference": "bd7351c88f3a797ea8977e68fe6a3f4d4c5f457f",
+ "url": "https://api.github.com/repos/infection/infection/zipball/feea2a48a8aeedd3a4d2105167b41a46f0e568a3",
+ "reference": "feea2a48a8aeedd3a4d2105167b41a46f0e568a3",
"shasum": ""
},
"require": {
- "colinodell/json5": "^2.2",
+ "colinodell/json5": "^2.2 || ^3.0",
"composer-runtime-api": "^2.0",
"composer/xdebug-handler": "^2.0 || ^3.0",
"ext-dom": "*",
"ext-json": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
- "fidry/cpu-core-counter": "^0.4.0",
+ "fidry/cpu-core-counter": "^0.4.0 || ^0.5.0 || ^1.0",
"infection/abstract-testframework-adapter": "^0.5.0",
"infection/extension-installer": "^0.1.0",
"infection/include-interceptor": "^0.2.5",
- "justinrainbow/json-schema": "^5.2.10",
- "nikic/php-parser": "^4.15.1",
+ "infection/mutator": "^0.4",
+ "justinrainbow/json-schema": "^5.3 || ^6.0",
+ "nikic/php-parser": "^5.3",
"ondram/ci-detector": "^4.1.0",
- "php": "^8.0",
+ "php": "^8.2",
"sanmai/later": "^0.1.1",
"sanmai/pipeline": "^5.1 || ^6",
- "sebastian/diff": "^3.0.2 || ^4.0 || ^5.0",
- "symfony/console": "^5.4 || ^6.0",
- "symfony/filesystem": "^5.4 || ^6.0",
- "symfony/finder": "^5.4 || ^6.0",
- "symfony/process": "^5.4 || ^6.0",
- "thecodingmachine/safe": "^2.1.2",
+ "sebastian/diff": "^3.0.2 || ^4.0 || ^5.0 || ^6.0 || ^7.0",
+ "symfony/console": "^6.4 || ^7.0",
+ "symfony/filesystem": "^6.4 || ^7.0",
+ "symfony/finder": "^6.4 || ^7.0",
+ "symfony/process": "^6.4 || ^7.0",
+ "thecodingmachine/safe": "^v3.0",
"webmozart/assert": "^1.11"
},
"conflict": {
+ "antecedent/patchwork": "<2.1.25",
"dg/bypass-finals": "<1.4.1",
"phpunit/php-code-coverage": ">9,<9.1.4 || >9.2.17,<9.2.21"
},
"require-dev": {
- "brianium/paratest": "^6.3",
"ext-simplexml": "*",
- "fidry/makefile": "^0.2.0",
- "helmich/phpunit-json-assert": "^3.0",
- "phpspec/prophecy-phpunit": "^2.0",
- "phpstan/extension-installer": "^1.1.0",
- "phpstan/phpstan": "^1.3.0",
- "phpstan/phpstan-phpunit": "^1.0.0",
- "phpstan/phpstan-strict-rules": "^1.1.0",
- "phpstan/phpstan-webmozart-assert": "^1.0.2",
- "phpunit/phpunit": "^9.5.5",
- "symfony/phpunit-bridge": "^5.4 || ^6.0",
- "symfony/yaml": "^5.4 || ^6.0",
- "thecodingmachine/phpstan-safe-rule": "^1.2.0"
+ "fidry/makefile": "^1.0",
+ "phpstan/extension-installer": "^1.4",
+ "phpstan/phpstan": "^2.1",
+ "phpstan/phpstan-phpunit": "^2.0",
+ "phpstan/phpstan-strict-rules": "^2.0",
+ "phpstan/phpstan-webmozart-assert": "^2.0",
+ "phpunit/phpunit": "^11.5",
+ "rector/rector": "^2.0",
+ "sidz/phpstan-rules": "^0.5.1",
+ "symfony/yaml": "^6.4 || ^7.0",
+ "thecodingmachine/phpstan-safe-rule": "^1.4"
},
"bin": [
"bin/infection"
@@ -732,7 +642,60 @@
],
"support": {
"issues": "https://github.com/infection/infection/issues",
- "source": "https://github.com/infection/infection/tree/0.26.19"
+ "source": "https://github.com/infection/infection/tree/0.29.14"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/infection",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/infection",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2025-03-02T18:49:12+00:00"
+ },
+ {
+ "name": "infection/mutator",
+ "version": "0.4.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/infection/mutator.git",
+ "reference": "3c976d721b02b32f851ee4e15d553ef1e9186d1d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/infection/mutator/zipball/3c976d721b02b32f851ee4e15d553ef1e9186d1d",
+ "reference": "3c976d721b02b32f851ee4e15d553ef1e9186d1d",
+ "shasum": ""
+ },
+ "require": {
+ "nikic/php-parser": "^5.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.6 || ^10"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Infection\\Mutator\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Maks Rafalko",
+ "email": "maks.rafalko@gmail.com"
+ }
+ ],
+ "description": "Mutator interface to implement custom mutators (mutation operators) for Infection",
+ "support": {
+ "issues": "https://github.com/infection/mutator/issues",
+ "source": "https://github.com/infection/mutator/tree/0.4.1"
},
"funding": [
{
@@ -744,29 +707,34 @@
"type": "open_collective"
}
],
- "time": "2023-02-05T21:47:26+00:00"
+ "time": "2025-04-29T08:19:52+00:00"
},
{
"name": "justinrainbow/json-schema",
- "version": "5.2.12",
+ "version": "6.4.1",
"source": {
"type": "git",
- "url": "https://github.com/justinrainbow/json-schema.git",
- "reference": "ad87d5a5ca981228e0e205c2bc7dfb8e24559b60"
+ "url": "https://github.com/jsonrainbow/json-schema.git",
+ "reference": "35d262c94959571e8736db1e5c9bc36ab94ae900"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/ad87d5a5ca981228e0e205c2bc7dfb8e24559b60",
- "reference": "ad87d5a5ca981228e0e205c2bc7dfb8e24559b60",
+ "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/35d262c94959571e8736db1e5c9bc36ab94ae900",
+ "reference": "35d262c94959571e8736db1e5c9bc36ab94ae900",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "ext-json": "*",
+ "marc-mabe/php-enum": "^4.0",
+ "php": "^7.2 || ^8.0"
},
"require-dev": {
- "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1",
+ "friendsofphp/php-cs-fixer": "3.3.0",
"json-schema/json-schema-test-suite": "1.2.0",
- "phpunit/phpunit": "^4.8.35"
+ "marc-mabe/php-enum-phpstan": "^2.0",
+ "phpspec/prophecy": "^1.19",
+ "phpstan/phpstan": "^1.12",
+ "phpunit/phpunit": "^8.5"
},
"bin": [
"bin/validate-json"
@@ -774,7 +742,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "5.0.x-dev"
+ "dev-master": "6.x-dev"
}
},
"autoload": {
@@ -805,29 +773,102 @@
}
],
"description": "A library to validate a json schema.",
- "homepage": "https://github.com/justinrainbow/json-schema",
+ "homepage": "https://github.com/jsonrainbow/json-schema",
"keywords": [
"json",
"schema"
],
"support": {
- "issues": "https://github.com/justinrainbow/json-schema/issues",
- "source": "https://github.com/justinrainbow/json-schema/tree/5.2.12"
+ "issues": "https://github.com/jsonrainbow/json-schema/issues",
+ "source": "https://github.com/jsonrainbow/json-schema/tree/6.4.1"
+ },
+ "time": "2025-04-04T13:08:07+00:00"
+ },
+ {
+ "name": "marc-mabe/php-enum",
+ "version": "v4.7.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/marc-mabe/php-enum.git",
+ "reference": "7159809e5cfa041dca28e61f7f7ae58063aae8ed"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/marc-mabe/php-enum/zipball/7159809e5cfa041dca28e61f7f7ae58063aae8ed",
+ "reference": "7159809e5cfa041dca28e61f7f7ae58063aae8ed",
+ "shasum": ""
+ },
+ "require": {
+ "ext-reflection": "*",
+ "php": "^7.1 | ^8.0"
+ },
+ "require-dev": {
+ "phpbench/phpbench": "^0.16.10 || ^1.0.4",
+ "phpstan/phpstan": "^1.3.1",
+ "phpunit/phpunit": "^7.5.20 | ^8.5.22 | ^9.5.11",
+ "vimeo/psalm": "^4.17.0 | ^5.26.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-3.x": "3.2-dev",
+ "dev-master": "4.7-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "MabeEnum\\": "src/"
+ },
+ "classmap": [
+ "stubs/Stringable.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Marc Bennewitz",
+ "email": "dev@mabe.berlin",
+ "homepage": "https://mabe.berlin/",
+ "role": "Lead"
+ }
+ ],
+ "description": "Simple and fast implementation of enumerations with native PHP",
+ "homepage": "https://github.com/marc-mabe/php-enum",
+ "keywords": [
+ "enum",
+ "enum-map",
+ "enum-set",
+ "enumeration",
+ "enumerator",
+ "enummap",
+ "enumset",
+ "map",
+ "set",
+ "type",
+ "type-hint",
+ "typehint"
+ ],
+ "support": {
+ "issues": "https://github.com/marc-mabe/php-enum/issues",
+ "source": "https://github.com/marc-mabe/php-enum/tree/v4.7.1"
},
- "time": "2022-04-13T08:02:27+00:00"
+ "time": "2024-11-28T04:54:44+00:00"
},
{
"name": "myclabs/deep-copy",
- "version": "1.11.1",
+ "version": "1.13.1",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
- "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c"
+ "reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
- "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/1720ddd719e16cf0db4eb1c6eca108031636d46c",
+ "reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c",
"shasum": ""
},
"require": {
@@ -835,11 +876,12 @@
},
"conflict": {
"doctrine/collections": "<1.6.8",
- "doctrine/common": "<2.13.3 || >=3,<3.2.2"
+ "doctrine/common": "<2.13.3 || >=3 <3.2.2"
},
"require-dev": {
"doctrine/collections": "^1.6.8",
"doctrine/common": "^2.13.3 || ^3.2.2",
+ "phpspec/prophecy": "^1.10",
"phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
},
"type": "library",
@@ -865,7 +907,7 @@
],
"support": {
"issues": "https://github.com/myclabs/DeepCopy/issues",
- "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1"
+ "source": "https://github.com/myclabs/DeepCopy/tree/1.13.1"
},
"funding": [
{
@@ -873,29 +915,31 @@
"type": "tidelift"
}
],
- "time": "2023-03-08T13:26:56+00:00"
+ "time": "2025-04-29T12:36:36+00:00"
},
{
"name": "nikic/php-parser",
- "version": "v4.15.4",
+ "version": "v5.4.0",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
- "reference": "6bb5176bc4af8bcb7d926f88718db9b96a2d4290"
+ "reference": "447a020a1f875a434d62f2a401f53b82a396e494"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/6bb5176bc4af8bcb7d926f88718db9b96a2d4290",
- "reference": "6bb5176bc4af8bcb7d926f88718db9b96a2d4290",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494",
+ "reference": "447a020a1f875a434d62f2a401f53b82a396e494",
"shasum": ""
},
"require": {
+ "ext-ctype": "*",
+ "ext-json": "*",
"ext-tokenizer": "*",
- "php": ">=7.0"
+ "php": ">=7.4"
},
"require-dev": {
"ircmaxell/php-yacc": "^0.0.7",
- "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
+ "phpunit/phpunit": "^9.0"
},
"bin": [
"bin/php-parse"
@@ -903,7 +947,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.9-dev"
+ "dev-master": "5.0-dev"
}
},
"autoload": {
@@ -927,35 +971,35 @@
],
"support": {
"issues": "https://github.com/nikic/PHP-Parser/issues",
- "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.4"
+ "source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0"
},
- "time": "2023-03-05T19:49:14+00:00"
+ "time": "2024-12-30T11:07:19+00:00"
},
{
"name": "ondram/ci-detector",
- "version": "4.1.0",
+ "version": "4.2.0",
"source": {
"type": "git",
"url": "https://github.com/OndraM/ci-detector.git",
- "reference": "8a4b664e916df82ff26a44709942dfd593fa6f30"
+ "reference": "8b0223b5ed235fd377c75fdd1bfcad05c0f168b8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/OndraM/ci-detector/zipball/8a4b664e916df82ff26a44709942dfd593fa6f30",
- "reference": "8a4b664e916df82ff26a44709942dfd593fa6f30",
+ "url": "https://api.github.com/repos/OndraM/ci-detector/zipball/8b0223b5ed235fd377c75fdd1bfcad05c0f168b8",
+ "reference": "8b0223b5ed235fd377c75fdd1bfcad05c0f168b8",
"shasum": ""
},
"require": {
- "php": "^7.1 || ^8.0"
+ "php": "^7.4 || ^8.0"
},
"require-dev": {
- "ergebnis/composer-normalize": "^2.2",
- "lmc/coding-standard": "^1.3 || ^2.1",
+ "ergebnis/composer-normalize": "^2.13.2",
+ "lmc/coding-standard": "^3.0.0",
"php-parallel-lint/php-parallel-lint": "^1.2",
- "phpstan/extension-installer": "^1.0.5",
- "phpstan/phpstan": "^0.12.58",
- "phpstan/phpstan-phpunit": "^0.12.16",
- "phpunit/phpunit": "^7.1 || ^8.0 || ^9.0"
+ "phpstan/extension-installer": "^1.1.0",
+ "phpstan/phpstan": "^1.2.0",
+ "phpstan/phpstan-phpunit": "^1.0.0",
+ "phpunit/phpunit": "^9.6.13"
},
"type": "library",
"autoload": {
@@ -1005,26 +1049,27 @@
],
"support": {
"issues": "https://github.com/OndraM/ci-detector/issues",
- "source": "https://github.com/OndraM/ci-detector/tree/4.1.0"
+ "source": "https://github.com/OndraM/ci-detector/tree/4.2.0"
},
- "time": "2021-04-14T09:16:52+00:00"
+ "time": "2024-03-12T13:22:30+00:00"
},
{
"name": "phar-io/manifest",
- "version": "2.0.3",
+ "version": "2.0.4",
"source": {
"type": "git",
"url": "https://github.com/phar-io/manifest.git",
- "reference": "97803eca37d319dfa7826cc2437fc020857acb53"
+ "reference": "54750ef60c58e43759730615a392c31c80e23176"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53",
- "reference": "97803eca37d319dfa7826cc2437fc020857acb53",
+ "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176",
+ "reference": "54750ef60c58e43759730615a392c31c80e23176",
"shasum": ""
},
"require": {
"ext-dom": "*",
+ "ext-libxml": "*",
"ext-phar": "*",
"ext-xmlwriter": "*",
"phar-io/version": "^3.0.1",
@@ -1065,9 +1110,15 @@
"description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
"support": {
"issues": "https://github.com/phar-io/manifest/issues",
- "source": "https://github.com/phar-io/manifest/tree/2.0.3"
+ "source": "https://github.com/phar-io/manifest/tree/2.0.4"
},
- "time": "2021-07-20T11:28:43+00:00"
+ "funding": [
+ {
+ "url": "https://github.com/theseer",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-03T12:33:53+00:00"
},
{
"name": "phar-io/version",
@@ -1120,67 +1171,22 @@
},
"time": "2022-02-21T01:04:05+00:00"
},
- {
- "name": "phpstan/phpdoc-parser",
- "version": "1.16.1",
- "source": {
- "type": "git",
- "url": "https://github.com/phpstan/phpdoc-parser.git",
- "reference": "e27e92d939e2e3636f0a1f0afaba59692c0bf571"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/e27e92d939e2e3636f0a1f0afaba59692c0bf571",
- "reference": "e27e92d939e2e3636f0a1f0afaba59692c0bf571",
- "shasum": ""
- },
- "require": {
- "php": "^7.2 || ^8.0"
- },
- "require-dev": {
- "php-parallel-lint/php-parallel-lint": "^1.2",
- "phpstan/extension-installer": "^1.0",
- "phpstan/phpstan": "^1.5",
- "phpstan/phpstan-phpunit": "^1.1",
- "phpstan/phpstan-strict-rules": "^1.0",
- "phpunit/phpunit": "^9.5",
- "symfony/process": "^5.2"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "PHPStan\\PhpDocParser\\": [
- "src/"
- ]
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "description": "PHPDoc parser with support for nullable, intersection and generic types",
- "support": {
- "issues": "https://github.com/phpstan/phpdoc-parser/issues",
- "source": "https://github.com/phpstan/phpdoc-parser/tree/1.16.1"
- },
- "time": "2023-02-07T18:11:17+00:00"
- },
{
"name": "phpstan/phpstan",
- "version": "1.10.9",
+ "version": "2.1.14",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
- "reference": "9b13dafe3d66693d20fe5729c3dde1d31bb64703"
+ "reference": "8f2e03099cac24ff3b379864d171c5acbfc6b9a2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpstan/zipball/9b13dafe3d66693d20fe5729c3dde1d31bb64703",
- "reference": "9b13dafe3d66693d20fe5729c3dde1d31bb64703",
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/8f2e03099cac24ff3b379864d171c5acbfc6b9a2",
+ "reference": "8f2e03099cac24ff3b379864d171c5acbfc6b9a2",
"shasum": ""
},
"require": {
- "php": "^7.2|^8.0"
+ "php": "^7.4|^8.0"
},
"conflict": {
"phpstan/phpstan-shim": "*"
@@ -1219,45 +1225,40 @@
{
"url": "https://github.com/phpstan",
"type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan",
- "type": "tidelift"
}
],
- "time": "2023-03-30T08:58:01+00:00"
+ "time": "2025-05-02T15:32:28+00:00"
},
{
"name": "phpunit/php-code-coverage",
- "version": "9.2.26",
+ "version": "12.2.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
- "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1"
+ "reference": "448f2c504d86dbff3949dcd02c95aa85db2c7617"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/443bc6912c9bd5b409254a40f4b0f4ced7c80ea1",
- "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/448f2c504d86dbff3949dcd02c95aa85db2c7617",
+ "reference": "448f2c504d86dbff3949dcd02c95aa85db2c7617",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-libxml": "*",
"ext-xmlwriter": "*",
- "nikic/php-parser": "^4.15",
- "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"
+ "nikic/php-parser": "^5.4.0",
+ "php": ">=8.3",
+ "phpunit/php-file-iterator": "^6.0",
+ "phpunit/php-text-template": "^5.0",
+ "sebastian/complexity": "^5.0",
+ "sebastian/environment": "^8.0",
+ "sebastian/lines-of-code": "^4.0",
+ "sebastian/version": "^6.0",
+ "theseer/tokenizer": "^1.2.3"
},
"require-dev": {
- "phpunit/phpunit": "^9.3"
+ "phpunit/phpunit": "^12.1"
},
"suggest": {
"ext-pcov": "PHP extension that provides line coverage",
@@ -1266,7 +1267,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "9.2-dev"
+ "dev-main": "12.2.x-dev"
}
},
"autoload": {
@@ -1294,40 +1295,53 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
- "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.26"
+ "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
+ "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.2.1"
},
"funding": [
{
"url": "https://github.com/sebastianbergmann",
"type": "github"
+ },
+ {
+ "url": "https://liberapay.com/sebastianbergmann",
+ "type": "liberapay"
+ },
+ {
+ "url": "https://thanks.dev/u/gh/sebastianbergmann",
+ "type": "thanks_dev"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/phpunit/php-code-coverage",
+ "type": "tidelift"
}
],
- "time": "2023-03-06T12:58:08+00:00"
+ "time": "2025-05-04T05:25:05+00:00"
},
{
"name": "phpunit/php-file-iterator",
- "version": "3.0.6",
+ "version": "6.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
- "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf"
+ "reference": "961bc913d42fe24a257bfff826a5068079ac7782"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf",
- "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/961bc913d42fe24a257bfff826a5068079ac7782",
+ "reference": "961bc913d42fe24a257bfff826a5068079ac7782",
"shasum": ""
},
"require": {
- "php": ">=7.3"
+ "php": ">=8.3"
},
"require-dev": {
- "phpunit/phpunit": "^9.3"
+ "phpunit/phpunit": "^12.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0-dev"
+ "dev-main": "6.0-dev"
}
},
"autoload": {
@@ -1354,7 +1368,8 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
- "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6"
+ "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy",
+ "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/6.0.0"
},
"funding": [
{
@@ -1362,28 +1377,28 @@
"type": "github"
}
],
- "time": "2021-12-02T12:48:52+00:00"
+ "time": "2025-02-07T04:58:37+00:00"
},
{
"name": "phpunit/php-invoker",
- "version": "3.1.1",
+ "version": "6.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-invoker.git",
- "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67"
+ "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
- "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/12b54e689b07a25a9b41e57736dfab6ec9ae5406",
+ "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406",
"shasum": ""
},
"require": {
- "php": ">=7.3"
+ "php": ">=8.3"
},
"require-dev": {
"ext-pcntl": "*",
- "phpunit/phpunit": "^9.3"
+ "phpunit/phpunit": "^12.0"
},
"suggest": {
"ext-pcntl": "*"
@@ -1391,7 +1406,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.1-dev"
+ "dev-main": "6.0-dev"
}
},
"autoload": {
@@ -1417,7 +1432,8 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-invoker/issues",
- "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1"
+ "security": "https://github.com/sebastianbergmann/php-invoker/security/policy",
+ "source": "https://github.com/sebastianbergmann/php-invoker/tree/6.0.0"
},
"funding": [
{
@@ -1425,32 +1441,32 @@
"type": "github"
}
],
- "time": "2020-09-28T05:58:55+00:00"
+ "time": "2025-02-07T04:58:58+00:00"
},
{
"name": "phpunit/php-text-template",
- "version": "2.0.4",
+ "version": "5.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-text-template.git",
- "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28"
+ "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28",
- "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/e1367a453f0eda562eedb4f659e13aa900d66c53",
+ "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53",
"shasum": ""
},
"require": {
- "php": ">=7.3"
+ "php": ">=8.3"
},
"require-dev": {
- "phpunit/phpunit": "^9.3"
+ "phpunit/phpunit": "^12.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.0-dev"
+ "dev-main": "5.0-dev"
}
},
"autoload": {
@@ -1476,7 +1492,8 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-text-template/issues",
- "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4"
+ "security": "https://github.com/sebastianbergmann/php-text-template/security/policy",
+ "source": "https://github.com/sebastianbergmann/php-text-template/tree/5.0.0"
},
"funding": [
{
@@ -1484,32 +1501,32 @@
"type": "github"
}
],
- "time": "2020-10-26T05:33:50+00:00"
+ "time": "2025-02-07T04:59:16+00:00"
},
{
"name": "phpunit/php-timer",
- "version": "5.0.3",
+ "version": "8.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-timer.git",
- "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2"
+ "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2",
- "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc",
+ "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc",
"shasum": ""
},
"require": {
- "php": ">=7.3"
+ "php": ">=8.3"
},
"require-dev": {
- "phpunit/phpunit": "^9.3"
+ "phpunit/phpunit": "^12.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "5.0-dev"
+ "dev-main": "8.0-dev"
}
},
"autoload": {
@@ -1535,7 +1552,8 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-timer/issues",
- "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3"
+ "security": "https://github.com/sebastianbergmann/php-timer/security/policy",
+ "source": "https://github.com/sebastianbergmann/php-timer/tree/8.0.0"
},
"funding": [
{
@@ -1543,54 +1561,48 @@
"type": "github"
}
],
- "time": "2020-10-26T13:16:10+00:00"
+ "time": "2025-02-07T04:59:38+00:00"
},
{
"name": "phpunit/phpunit",
- "version": "9.6.6",
+ "version": "12.1.5",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "b65d59a059d3004a040c16a82e07bbdf6cfdd115"
+ "reference": "f93ef2198df8d54b3195bcee381a33be51d8705e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b65d59a059d3004a040c16a82e07bbdf6cfdd115",
- "reference": "b65d59a059d3004a040c16a82e07bbdf6cfdd115",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f93ef2198df8d54b3195bcee381a33be51d8705e",
+ "reference": "f93ef2198df8d54b3195bcee381a33be51d8705e",
"shasum": ""
},
"require": {
- "doctrine/instantiator": "^1.3.1 || ^2",
"ext-dom": "*",
"ext-json": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
"ext-xml": "*",
"ext-xmlwriter": "*",
- "myclabs/deep-copy": "^1.10.1",
- "phar-io/manifest": "^2.0.3",
- "phar-io/version": "^3.0.2",
- "php": ">=7.3",
- "phpunit/php-code-coverage": "^9.2.13",
- "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.8",
- "sebastian/diff": "^4.0.3",
- "sebastian/environment": "^5.1.3",
- "sebastian/exporter": "^4.0.5",
- "sebastian/global-state": "^5.0.1",
- "sebastian/object-enumerator": "^4.0.3",
- "sebastian/resource-operations": "^3.0.3",
- "sebastian/type": "^3.2",
- "sebastian/version": "^3.0.2"
- },
- "suggest": {
- "ext-soap": "To be able to generate mocks based on WSDL files",
- "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
+ "myclabs/deep-copy": "^1.13.1",
+ "phar-io/manifest": "^2.0.4",
+ "phar-io/version": "^3.2.1",
+ "php": ">=8.3",
+ "phpunit/php-code-coverage": "^12.2.1",
+ "phpunit/php-file-iterator": "^6.0.0",
+ "phpunit/php-invoker": "^6.0.0",
+ "phpunit/php-text-template": "^5.0.0",
+ "phpunit/php-timer": "^8.0.0",
+ "sebastian/cli-parser": "^4.0.0",
+ "sebastian/comparator": "^7.0.1",
+ "sebastian/diff": "^7.0.0",
+ "sebastian/environment": "^8.0.0",
+ "sebastian/exporter": "^7.0.0",
+ "sebastian/global-state": "^8.0.0",
+ "sebastian/object-enumerator": "^7.0.0",
+ "sebastian/type": "^6.0.2",
+ "sebastian/version": "^6.0.0",
+ "staabm/side-effects-detector": "^1.0.5"
},
"bin": [
"phpunit"
@@ -1598,7 +1610,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "9.6-dev"
+ "dev-main": "12.1-dev"
}
},
"autoload": {
@@ -1630,7 +1642,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
- "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.6"
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/12.1.5"
},
"funding": [
{
@@ -1641,12 +1653,20 @@
"url": "https://github.com/sebastianbergmann",
"type": "github"
},
+ {
+ "url": "https://liberapay.com/sebastianbergmann",
+ "type": "liberapay"
+ },
+ {
+ "url": "https://thanks.dev/u/gh/sebastianbergmann",
+ "type": "thanks_dev"
+ },
{
"url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit",
"type": "tidelift"
}
],
- "time": "2023-03-27T11:43:46+00:00"
+ "time": "2025-05-11T06:44:52+00:00"
},
{
"name": "psr/container",
@@ -1703,16 +1723,16 @@
},
{
"name": "psr/log",
- "version": "3.0.0",
+ "version": "3.0.2",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
- "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001"
+ "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001",
- "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
+ "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
"shasum": ""
},
"require": {
@@ -1747,37 +1767,43 @@
"psr-3"
],
"support": {
- "source": "https://github.com/php-fig/log/tree/3.0.0"
+ "source": "https://github.com/php-fig/log/tree/3.0.2"
},
- "time": "2021-07-14T16:46:02+00:00"
+ "time": "2024-09-11T13:17:53+00:00"
},
{
"name": "sanmai/later",
- "version": "0.1.2",
+ "version": "0.1.7",
"source": {
"type": "git",
"url": "https://github.com/sanmai/later.git",
- "reference": "9b659fecef2030193fd02402955bc39629d5606f"
+ "reference": "72a82d783864bca90412d8a26c1878f8981fee97"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sanmai/later/zipball/9b659fecef2030193fd02402955bc39629d5606f",
- "reference": "9b659fecef2030193fd02402955bc39629d5606f",
+ "url": "https://api.github.com/repos/sanmai/later/zipball/72a82d783864bca90412d8a26c1878f8981fee97",
+ "reference": "72a82d783864bca90412d8a26c1878f8981fee97",
"shasum": ""
},
"require": {
- "php": ">=7.1"
+ "php": ">=8.2"
},
"require-dev": {
- "friendsofphp/php-cs-fixer": "^2.13",
- "infection/infection": ">=0.10.5",
+ "ergebnis/composer-normalize": "^2.8",
+ "friendsofphp/php-cs-fixer": "^3.35.1",
+ "infection/infection": ">=0.27.6",
"phan/phan": ">=2",
"php-coveralls/php-coveralls": "^2.0",
- "phpstan/phpstan": ">=0.10",
- "phpunit/phpunit": ">=7.4",
+ "phpstan/phpstan": ">=1.4.5",
+ "phpunit/phpunit": ">=9.5 <10",
"vimeo/psalm": ">=2"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.1.x-dev"
+ }
+ },
"autoload": {
"files": [
"src/functions.php"
@@ -1799,7 +1825,7 @@
"description": "Later: deferred wrapper object",
"support": {
"issues": "https://github.com/sanmai/later/issues",
- "source": "https://github.com/sanmai/later/tree/0.1.2"
+ "source": "https://github.com/sanmai/later/tree/0.1.7"
},
"funding": [
{
@@ -1807,34 +1833,34 @@
"type": "github"
}
],
- "time": "2021-01-02T10:26:44+00:00"
+ "time": "2025-05-11T01:48:00+00:00"
},
{
"name": "sanmai/pipeline",
- "version": "v6.3",
+ "version": "6.12",
"source": {
"type": "git",
"url": "https://github.com/sanmai/pipeline.git",
- "reference": "929b115ca58d62b6b2574702df1ebde4562c7c43"
+ "reference": "ad7dbc3f773eeafb90d5459522fbd8f188532e25"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sanmai/pipeline/zipball/929b115ca58d62b6b2574702df1ebde4562c7c43",
- "reference": "929b115ca58d62b6b2574702df1ebde4562c7c43",
+ "url": "https://api.github.com/repos/sanmai/pipeline/zipball/ad7dbc3f773eeafb90d5459522fbd8f188532e25",
+ "reference": "ad7dbc3f773eeafb90d5459522fbd8f188532e25",
"shasum": ""
},
"require": {
- "php": "^7.1 || ^8.0"
+ "php": "^7.4 || ^8.0"
},
"require-dev": {
"ergebnis/composer-normalize": "^2.8",
- "friendsofphp/php-cs-fixer": "^3",
+ "friendsofphp/php-cs-fixer": "^3.17",
"infection/infection": ">=0.10.5",
- "league/pipeline": "^1.0 || ^0.3",
+ "league/pipeline": "^0.3 || ^1.0",
"phan/phan": ">=1.1",
"php-coveralls/php-coveralls": "^2.4.1",
"phpstan/phpstan": ">=0.10",
- "phpunit/phpunit": "^7.4 || ^8.1 || ^9.4",
+ "phpunit/phpunit": ">=9.4",
"vimeo/psalm": ">=2"
},
"type": "library",
@@ -1857,159 +1883,47 @@
],
"authors": [
{
- "name": "Alexey Kopytko",
- "email": "alexey@kopytko.com"
- }
- ],
- "description": "General-purpose collections pipeline",
- "support": {
- "issues": "https://github.com/sanmai/pipeline/issues",
- "source": "https://github.com/sanmai/pipeline/tree/v6.3"
- },
- "funding": [
- {
- "url": "https://github.com/sanmai",
- "type": "github"
- }
- ],
- "time": "2022-11-30T06:07:06+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"
+ "name": "Alexey Kopytko",
+ "email": "alexey@kopytko.com"
}
],
- "description": "Collection of value objects that represent the PHP code units",
- "homepage": "https://github.com/sebastianbergmann/code-unit",
+ "description": "General-purpose collections pipeline",
"support": {
- "issues": "https://github.com/sebastianbergmann/code-unit/issues",
- "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8"
+ "issues": "https://github.com/sanmai/pipeline/issues",
+ "source": "https://github.com/sanmai/pipeline/tree/6.12"
},
"funding": [
{
- "url": "https://github.com/sebastianbergmann",
+ "url": "https://github.com/sanmai",
"type": "github"
}
],
- "time": "2020-10-26T13:08:54+00:00"
+ "time": "2024-10-17T02:22:57+00:00"
},
{
- "name": "sebastian/code-unit-reverse-lookup",
- "version": "2.0.3",
+ "name": "sebastian/cli-parser",
+ "version": "4.0.0",
"source": {
"type": "git",
- "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
- "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5"
+ "url": "https://github.com/sebastianbergmann/cli-parser.git",
+ "reference": "6d584c727d9114bcdc14c86711cd1cad51778e7c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
- "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
+ "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/6d584c727d9114bcdc14c86711cd1cad51778e7c",
+ "reference": "6d584c727d9114bcdc14c86711cd1cad51778e7c",
"shasum": ""
},
"require": {
- "php": ">=7.3"
+ "php": ">=8.3"
},
"require-dev": {
- "phpunit/phpunit": "^9.3"
+ "phpunit/phpunit": "^12.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.0-dev"
+ "dev-main": "4.0-dev"
}
},
"autoload": {
@@ -2024,14 +1938,16 @@
"authors": [
{
"name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
}
],
- "description": "Looks up which function or method a line of code belongs to",
- "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
+ "description": "Library for parsing CLI options",
+ "homepage": "https://github.com/sebastianbergmann/cli-parser",
"support": {
- "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
- "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3"
+ "issues": "https://github.com/sebastianbergmann/cli-parser/issues",
+ "security": "https://github.com/sebastianbergmann/cli-parser/security/policy",
+ "source": "https://github.com/sebastianbergmann/cli-parser/tree/4.0.0"
},
"funding": [
{
@@ -2039,34 +1955,39 @@
"type": "github"
}
],
- "time": "2020-09-28T05:30:19+00:00"
+ "time": "2025-02-07T04:53:50+00:00"
},
{
"name": "sebastian/comparator",
- "version": "4.0.8",
+ "version": "7.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
- "reference": "fa0f136dd2334583309d32b62544682ee972b51a"
+ "reference": "b478f34614f934e0291598d0c08cbaba9644bee5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a",
- "reference": "fa0f136dd2334583309d32b62544682ee972b51a",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/b478f34614f934e0291598d0c08cbaba9644bee5",
+ "reference": "b478f34614f934e0291598d0c08cbaba9644bee5",
"shasum": ""
},
"require": {
- "php": ">=7.3",
- "sebastian/diff": "^4.0",
- "sebastian/exporter": "^4.0"
+ "ext-dom": "*",
+ "ext-mbstring": "*",
+ "php": ">=8.3",
+ "sebastian/diff": "^7.0",
+ "sebastian/exporter": "^7.0"
},
"require-dev": {
- "phpunit/phpunit": "^9.3"
+ "phpunit/phpunit": "^12.0"
+ },
+ "suggest": {
+ "ext-bcmath": "For comparing BcMath\\Number objects"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.0-dev"
+ "dev-main": "7.0-dev"
}
},
"autoload": {
@@ -2105,7 +2026,8 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/comparator/issues",
- "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8"
+ "security": "https://github.com/sebastianbergmann/comparator/security/policy",
+ "source": "https://github.com/sebastianbergmann/comparator/tree/7.0.1"
},
"funding": [
{
@@ -2113,33 +2035,33 @@
"type": "github"
}
],
- "time": "2022-09-14T12:41:17+00:00"
+ "time": "2025-03-07T07:00:32+00:00"
},
{
"name": "sebastian/complexity",
- "version": "2.0.2",
+ "version": "5.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/complexity.git",
- "reference": "739b35e53379900cc9ac327b2147867b8b6efd88"
+ "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88",
- "reference": "739b35e53379900cc9ac327b2147867b8b6efd88",
+ "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/bad4316aba5303d0221f43f8cee37eb58d384bbb",
+ "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb",
"shasum": ""
},
"require": {
- "nikic/php-parser": "^4.7",
- "php": ">=7.3"
+ "nikic/php-parser": "^5.0",
+ "php": ">=8.3"
},
"require-dev": {
- "phpunit/phpunit": "^9.3"
+ "phpunit/phpunit": "^12.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.0-dev"
+ "dev-main": "5.0-dev"
}
},
"autoload": {
@@ -2162,7 +2084,8 @@
"homepage": "https://github.com/sebastianbergmann/complexity",
"support": {
"issues": "https://github.com/sebastianbergmann/complexity/issues",
- "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2"
+ "security": "https://github.com/sebastianbergmann/complexity/security/policy",
+ "source": "https://github.com/sebastianbergmann/complexity/tree/5.0.0"
},
"funding": [
{
@@ -2170,33 +2093,33 @@
"type": "github"
}
],
- "time": "2020-10-26T15:52:27+00:00"
+ "time": "2025-02-07T04:55:25+00:00"
},
{
"name": "sebastian/diff",
- "version": "4.0.4",
+ "version": "7.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/diff.git",
- "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d"
+ "reference": "7ab1ea946c012266ca32390913653d844ecd085f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d",
- "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7ab1ea946c012266ca32390913653d844ecd085f",
+ "reference": "7ab1ea946c012266ca32390913653d844ecd085f",
"shasum": ""
},
"require": {
- "php": ">=7.3"
+ "php": ">=8.3"
},
"require-dev": {
- "phpunit/phpunit": "^9.3",
- "symfony/process": "^4.2 || ^5"
+ "phpunit/phpunit": "^12.0",
+ "symfony/process": "^7.2"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.0-dev"
+ "dev-main": "7.0-dev"
}
},
"autoload": {
@@ -2228,7 +2151,8 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/diff/issues",
- "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4"
+ "security": "https://github.com/sebastianbergmann/diff/security/policy",
+ "source": "https://github.com/sebastianbergmann/diff/tree/7.0.0"
},
"funding": [
{
@@ -2236,27 +2160,27 @@
"type": "github"
}
],
- "time": "2020-10-26T13:10:38+00:00"
+ "time": "2025-02-07T04:55:46+00:00"
},
{
"name": "sebastian/environment",
- "version": "5.1.5",
+ "version": "8.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/environment.git",
- "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed"
+ "reference": "8afe311eca49171bf95405cc0078be9a3821f9f2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed",
- "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8afe311eca49171bf95405cc0078be9a3821f9f2",
+ "reference": "8afe311eca49171bf95405cc0078be9a3821f9f2",
"shasum": ""
},
"require": {
- "php": ">=7.3"
+ "php": ">=8.3"
},
"require-dev": {
- "phpunit/phpunit": "^9.3"
+ "phpunit/phpunit": "^12.0"
},
"suggest": {
"ext-posix": "*"
@@ -2264,7 +2188,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "5.1-dev"
+ "dev-main": "8.0-dev"
}
},
"autoload": {
@@ -2283,7 +2207,7 @@
}
],
"description": "Provides functionality to handle HHVM/PHP environments",
- "homepage": "http://www.github.com/sebastianbergmann/environment",
+ "homepage": "https://github.com/sebastianbergmann/environment",
"keywords": [
"Xdebug",
"environment",
@@ -2291,7 +2215,8 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/environment/issues",
- "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5"
+ "security": "https://github.com/sebastianbergmann/environment/security/policy",
+ "source": "https://github.com/sebastianbergmann/environment/tree/8.0.0"
},
"funding": [
{
@@ -2299,34 +2224,34 @@
"type": "github"
}
],
- "time": "2023-02-03T06:03:51+00:00"
+ "time": "2025-02-07T04:56:08+00:00"
},
{
"name": "sebastian/exporter",
- "version": "4.0.5",
+ "version": "7.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git",
- "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d"
+ "reference": "76432aafc58d50691a00d86d0632f1217a47b688"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d",
- "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/76432aafc58d50691a00d86d0632f1217a47b688",
+ "reference": "76432aafc58d50691a00d86d0632f1217a47b688",
"shasum": ""
},
"require": {
- "php": ">=7.3",
- "sebastian/recursion-context": "^4.0"
+ "ext-mbstring": "*",
+ "php": ">=8.3",
+ "sebastian/recursion-context": "^7.0"
},
"require-dev": {
- "ext-mbstring": "*",
- "phpunit/phpunit": "^9.3"
+ "phpunit/phpunit": "^12.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.0-dev"
+ "dev-main": "7.0-dev"
}
},
"autoload": {
@@ -2368,7 +2293,8 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/exporter/issues",
- "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5"
+ "security": "https://github.com/sebastianbergmann/exporter/security/policy",
+ "source": "https://github.com/sebastianbergmann/exporter/tree/7.0.0"
},
"funding": [
{
@@ -2376,38 +2302,35 @@
"type": "github"
}
],
- "time": "2022-09-14T06:03:37+00:00"
+ "time": "2025-02-07T04:56:42+00:00"
},
{
"name": "sebastian/global-state",
- "version": "5.0.5",
+ "version": "8.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/global-state.git",
- "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2"
+ "reference": "570a2aeb26d40f057af686d63c4e99b075fb6cbc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2",
- "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/570a2aeb26d40f057af686d63c4e99b075fb6cbc",
+ "reference": "570a2aeb26d40f057af686d63c4e99b075fb6cbc",
"shasum": ""
},
"require": {
- "php": ">=7.3",
- "sebastian/object-reflector": "^2.0",
- "sebastian/recursion-context": "^4.0"
+ "php": ">=8.3",
+ "sebastian/object-reflector": "^5.0",
+ "sebastian/recursion-context": "^7.0"
},
"require-dev": {
"ext-dom": "*",
- "phpunit/phpunit": "^9.3"
- },
- "suggest": {
- "ext-uopz": "*"
+ "phpunit/phpunit": "^12.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "5.0-dev"
+ "dev-main": "8.0-dev"
}
},
"autoload": {
@@ -2426,13 +2349,14 @@
}
],
"description": "Snapshotting of global state",
- "homepage": "http://www.github.com/sebastianbergmann/global-state",
+ "homepage": "https://www.github.com/sebastianbergmann/global-state",
"keywords": [
"global state"
],
"support": {
"issues": "https://github.com/sebastianbergmann/global-state/issues",
- "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5"
+ "security": "https://github.com/sebastianbergmann/global-state/security/policy",
+ "source": "https://github.com/sebastianbergmann/global-state/tree/8.0.0"
},
"funding": [
{
@@ -2440,33 +2364,33 @@
"type": "github"
}
],
- "time": "2022-02-14T08:28:10+00:00"
+ "time": "2025-02-07T04:56:59+00:00"
},
{
"name": "sebastian/lines-of-code",
- "version": "1.0.3",
+ "version": "4.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/lines-of-code.git",
- "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc"
+ "reference": "97ffee3bcfb5805568d6af7f0f893678fc076d2f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc",
- "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc",
+ "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/97ffee3bcfb5805568d6af7f0f893678fc076d2f",
+ "reference": "97ffee3bcfb5805568d6af7f0f893678fc076d2f",
"shasum": ""
},
"require": {
- "nikic/php-parser": "^4.6",
- "php": ">=7.3"
+ "nikic/php-parser": "^5.0",
+ "php": ">=8.3"
},
"require-dev": {
- "phpunit/phpunit": "^9.3"
+ "phpunit/phpunit": "^12.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0-dev"
+ "dev-main": "4.0-dev"
}
},
"autoload": {
@@ -2489,7 +2413,8 @@
"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"
+ "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy",
+ "source": "https://github.com/sebastianbergmann/lines-of-code/tree/4.0.0"
},
"funding": [
{
@@ -2497,34 +2422,34 @@
"type": "github"
}
],
- "time": "2020-11-28T06:42:11+00:00"
+ "time": "2025-02-07T04:57:28+00:00"
},
{
"name": "sebastian/object-enumerator",
- "version": "4.0.4",
+ "version": "7.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/object-enumerator.git",
- "reference": "5c9eeac41b290a3712d88851518825ad78f45c71"
+ "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71",
- "reference": "5c9eeac41b290a3712d88851518825ad78f45c71",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1effe8e9b8e068e9ae228e542d5d11b5d16db894",
+ "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894",
"shasum": ""
},
"require": {
- "php": ">=7.3",
- "sebastian/object-reflector": "^2.0",
- "sebastian/recursion-context": "^4.0"
+ "php": ">=8.3",
+ "sebastian/object-reflector": "^5.0",
+ "sebastian/recursion-context": "^7.0"
},
"require-dev": {
- "phpunit/phpunit": "^9.3"
+ "phpunit/phpunit": "^12.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.0-dev"
+ "dev-main": "7.0-dev"
}
},
"autoload": {
@@ -2546,7 +2471,8 @@
"homepage": "https://github.com/sebastianbergmann/object-enumerator/",
"support": {
"issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
- "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4"
+ "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy",
+ "source": "https://github.com/sebastianbergmann/object-enumerator/tree/7.0.0"
},
"funding": [
{
@@ -2554,32 +2480,32 @@
"type": "github"
}
],
- "time": "2020-10-26T13:12:34+00:00"
+ "time": "2025-02-07T04:57:48+00:00"
},
{
"name": "sebastian/object-reflector",
- "version": "2.0.4",
+ "version": "5.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/object-reflector.git",
- "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7"
+ "reference": "4bfa827c969c98be1e527abd576533293c634f6a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7",
- "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/4bfa827c969c98be1e527abd576533293c634f6a",
+ "reference": "4bfa827c969c98be1e527abd576533293c634f6a",
"shasum": ""
},
"require": {
- "php": ">=7.3"
+ "php": ">=8.3"
},
"require-dev": {
- "phpunit/phpunit": "^9.3"
+ "phpunit/phpunit": "^12.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.0-dev"
+ "dev-main": "5.0-dev"
}
},
"autoload": {
@@ -2601,7 +2527,8 @@
"homepage": "https://github.com/sebastianbergmann/object-reflector/",
"support": {
"issues": "https://github.com/sebastianbergmann/object-reflector/issues",
- "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4"
+ "security": "https://github.com/sebastianbergmann/object-reflector/security/policy",
+ "source": "https://github.com/sebastianbergmann/object-reflector/tree/5.0.0"
},
"funding": [
{
@@ -2609,32 +2536,32 @@
"type": "github"
}
],
- "time": "2020-10-26T13:14:26+00:00"
+ "time": "2025-02-07T04:58:17+00:00"
},
{
"name": "sebastian/recursion-context",
- "version": "4.0.5",
+ "version": "7.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/recursion-context.git",
- "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1"
+ "reference": "c405ae3a63e01b32eb71577f8ec1604e39858a7c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1",
- "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/c405ae3a63e01b32eb71577f8ec1604e39858a7c",
+ "reference": "c405ae3a63e01b32eb71577f8ec1604e39858a7c",
"shasum": ""
},
"require": {
- "php": ">=7.3"
+ "php": ">=8.3"
},
"require-dev": {
- "phpunit/phpunit": "^9.3"
+ "phpunit/phpunit": "^12.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.0-dev"
+ "dev-main": "7.0-dev"
}
},
"autoload": {
@@ -2664,62 +2591,8 @@
"homepage": "https://github.com/sebastianbergmann/recursion-context",
"support": {
"issues": "https://github.com/sebastianbergmann/recursion-context/issues",
- "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2023-02-03T06:07:39+00:00"
- },
- {
- "name": "sebastian/resource-operations",
- "version": "3.0.3",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/resource-operations.git",
- "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
- "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
- "shasum": ""
- },
- "require": {
- "php": ">=7.3"
- },
- "require-dev": {
- "phpunit/phpunit": "^9.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Provides a list of PHP built-in functions that operate on resources",
- "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/3.0.3"
+ "security": "https://github.com/sebastianbergmann/recursion-context/security/policy",
+ "source": "https://github.com/sebastianbergmann/recursion-context/tree/7.0.0"
},
"funding": [
{
@@ -2727,32 +2600,32 @@
"type": "github"
}
],
- "time": "2020-09-28T06:45:17+00:00"
+ "time": "2025-02-07T05:00:01+00:00"
},
{
"name": "sebastian/type",
- "version": "3.2.1",
+ "version": "6.0.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/type.git",
- "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7"
+ "reference": "1d7cd6e514384c36d7a390347f57c385d4be6069"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7",
- "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7",
+ "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/1d7cd6e514384c36d7a390347f57c385d4be6069",
+ "reference": "1d7cd6e514384c36d7a390347f57c385d4be6069",
"shasum": ""
},
"require": {
- "php": ">=7.3"
+ "php": ">=8.3"
},
"require-dev": {
- "phpunit/phpunit": "^9.5"
+ "phpunit/phpunit": "^12.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.2-dev"
+ "dev-main": "6.0-dev"
}
},
"autoload": {
@@ -2775,7 +2648,8 @@
"homepage": "https://github.com/sebastianbergmann/type",
"support": {
"issues": "https://github.com/sebastianbergmann/type/issues",
- "source": "https://github.com/sebastianbergmann/type/tree/3.2.1"
+ "security": "https://github.com/sebastianbergmann/type/security/policy",
+ "source": "https://github.com/sebastianbergmann/type/tree/6.0.2"
},
"funding": [
{
@@ -2783,29 +2657,29 @@
"type": "github"
}
],
- "time": "2023-02-03T06:13:03+00:00"
+ "time": "2025-03-18T13:37:31+00:00"
},
{
"name": "sebastian/version",
- "version": "3.0.2",
+ "version": "6.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/version.git",
- "reference": "c6c1022351a901512170118436c764e473f6de8c"
+ "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c",
- "reference": "c6c1022351a901512170118436c764e473f6de8c",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/3e6ccf7657d4f0a59200564b08cead899313b53c",
+ "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c",
"shasum": ""
},
"require": {
- "php": ">=7.3"
+ "php": ">=8.3"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0-dev"
+ "dev-main": "6.0-dev"
}
},
"autoload": {
@@ -2828,7 +2702,8 @@
"homepage": "https://github.com/sebastianbergmann/version",
"support": {
"issues": "https://github.com/sebastianbergmann/version/issues",
- "source": "https://github.com/sebastianbergmann/version/tree/3.0.2"
+ "security": "https://github.com/sebastianbergmann/version/security/policy",
+ "source": "https://github.com/sebastianbergmann/version/tree/6.0.0"
},
"funding": [
{
@@ -2836,175 +2711,186 @@
"type": "github"
}
],
- "time": "2020-09-28T06:39:44+00:00"
+ "time": "2025-02-07T05:00:38+00:00"
},
{
- "name": "slevomat/coding-standard",
- "version": "8.9.1",
+ "name": "squizlabs/php_codesniffer",
+ "version": "3.13.0",
"source": {
"type": "git",
- "url": "https://github.com/slevomat/coding-standard.git",
- "reference": "3d4fe0c803ae15829ef72d90d3d4eee3dd9f79b2"
+ "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git",
+ "reference": "65ff2489553b83b4597e89c3b8b721487011d186"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/3d4fe0c803ae15829ef72d90d3d4eee3dd9f79b2",
- "reference": "3d4fe0c803ae15829ef72d90d3d4eee3dd9f79b2",
+ "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/65ff2489553b83b4597e89c3b8b721487011d186",
+ "reference": "65ff2489553b83b4597e89c3b8b721487011d186",
"shasum": ""
},
"require": {
- "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.0",
- "php": "^7.2 || ^8.0",
- "phpstan/phpdoc-parser": ">=1.16.0 <1.17.0",
- "squizlabs/php_codesniffer": "^3.7.1"
+ "ext-simplexml": "*",
+ "ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
+ "php": ">=5.4.0"
},
"require-dev": {
- "phing/phing": "2.17.4",
- "php-parallel-lint/php-parallel-lint": "1.3.2",
- "phpstan/phpstan": "1.4.10|1.10.8",
- "phpstan/phpstan-deprecation-rules": "1.1.3",
- "phpstan/phpstan-phpunit": "1.0.0|1.3.10",
- "phpstan/phpstan-strict-rules": "1.5.0",
- "phpunit/phpunit": "7.5.20|8.5.21|9.6.5"
- },
- "type": "phpcodesniffer-standard",
+ "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4"
+ },
+ "bin": [
+ "bin/phpcbf",
+ "bin/phpcs"
+ ],
+ "type": "library",
"extra": {
"branch-alias": {
- "dev-master": "8.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "SlevomatCodingStandard\\": "SlevomatCodingStandard/"
+ "dev-master": "3.x-dev"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Greg Sherwood",
+ "role": "Former lead"
+ },
+ {
+ "name": "Juliette Reinders Folmer",
+ "role": "Current lead"
+ },
+ {
+ "name": "Contributors",
+ "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors"
+ }
],
- "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.",
+ "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
+ "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer",
"keywords": [
- "dev",
- "phpcs"
+ "phpcs",
+ "standards",
+ "static analysis"
],
"support": {
- "issues": "https://github.com/slevomat/coding-standard/issues",
- "source": "https://github.com/slevomat/coding-standard/tree/8.9.1"
+ "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues",
+ "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy",
+ "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer",
+ "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki"
},
"funding": [
{
- "url": "https://github.com/kukulich",
+ "url": "https://github.com/PHPCSStandards",
"type": "github"
},
{
- "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard",
- "type": "tidelift"
+ "url": "https://github.com/jrfnl",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/php_codesniffer",
+ "type": "open_collective"
+ },
+ {
+ "url": "https://thanks.dev/u/gh/phpcsstandards",
+ "type": "thanks_dev"
}
],
- "time": "2023-03-27T11:00:16+00:00"
+ "time": "2025-05-11T03:36:00+00:00"
},
{
- "name": "squizlabs/php_codesniffer",
- "version": "3.7.2",
+ "name": "staabm/side-effects-detector",
+ "version": "1.0.5",
"source": {
"type": "git",
- "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
- "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879"
+ "url": "https://github.com/staabm/side-effects-detector.git",
+ "reference": "d8334211a140ce329c13726d4a715adbddd0a163"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879",
- "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879",
+ "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163",
+ "reference": "d8334211a140ce329c13726d4a715adbddd0a163",
"shasum": ""
},
"require": {
- "ext-simplexml": "*",
"ext-tokenizer": "*",
- "ext-xmlwriter": "*",
- "php": ">=5.4.0"
+ "php": "^7.4 || ^8.0"
},
"require-dev": {
- "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
+ "phpstan/extension-installer": "^1.4.3",
+ "phpstan/phpstan": "^1.12.6",
+ "phpunit/phpunit": "^9.6.21",
+ "symfony/var-dumper": "^5.4.43",
+ "tomasvotruba/type-coverage": "1.0.0",
+ "tomasvotruba/unused-public": "1.0.0"
},
- "bin": [
- "bin/phpcs",
- "bin/phpcbf"
- ],
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.x-dev"
- }
+ "autoload": {
+ "classmap": [
+ "lib/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Greg Sherwood",
- "role": "lead"
- }
+ "MIT"
],
- "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
- "homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
+ "description": "A static analysis tool to detect side effects in PHP code",
"keywords": [
- "phpcs",
- "standards",
"static analysis"
],
"support": {
- "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues",
- "source": "https://github.com/squizlabs/PHP_CodeSniffer",
- "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki"
+ "issues": "https://github.com/staabm/side-effects-detector/issues",
+ "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5"
},
- "time": "2023-02-22T23:07:41+00:00"
+ "funding": [
+ {
+ "url": "https://github.com/staabm",
+ "type": "github"
+ }
+ ],
+ "time": "2024-10-20T05:08:20+00:00"
},
{
"name": "symfony/console",
- "version": "v6.2.8",
+ "version": "v7.2.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "3582d68a64a86ec25240aaa521ec8bc2342b369b"
+ "reference": "0e2e3f38c192e93e622e41ec37f4ca70cfedf218"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/3582d68a64a86ec25240aaa521ec8bc2342b369b",
- "reference": "3582d68a64a86ec25240aaa521ec8bc2342b369b",
+ "url": "https://api.github.com/repos/symfony/console/zipball/0e2e3f38c192e93e622e41ec37f4ca70cfedf218",
+ "reference": "0e2e3f38c192e93e622e41ec37f4ca70cfedf218",
"shasum": ""
},
"require": {
- "php": ">=8.1",
- "symfony/deprecation-contracts": "^2.1|^3",
+ "php": ">=8.2",
"symfony/polyfill-mbstring": "~1.0",
- "symfony/service-contracts": "^1.1|^2|^3",
- "symfony/string": "^5.4|^6.0"
+ "symfony/service-contracts": "^2.5|^3",
+ "symfony/string": "^6.4|^7.0"
},
"conflict": {
- "symfony/dependency-injection": "<5.4",
- "symfony/dotenv": "<5.4",
- "symfony/event-dispatcher": "<5.4",
- "symfony/lock": "<5.4",
- "symfony/process": "<5.4"
+ "symfony/dependency-injection": "<6.4",
+ "symfony/dotenv": "<6.4",
+ "symfony/event-dispatcher": "<6.4",
+ "symfony/lock": "<6.4",
+ "symfony/process": "<6.4"
},
"provide": {
"psr/log-implementation": "1.0|2.0|3.0"
},
"require-dev": {
"psr/log": "^1|^2|^3",
- "symfony/config": "^5.4|^6.0",
- "symfony/dependency-injection": "^5.4|^6.0",
- "symfony/event-dispatcher": "^5.4|^6.0",
- "symfony/lock": "^5.4|^6.0",
- "symfony/process": "^5.4|^6.0",
- "symfony/var-dumper": "^5.4|^6.0"
- },
- "suggest": {
- "psr/log": "For using the console logger",
- "symfony/event-dispatcher": "",
- "symfony/lock": "",
- "symfony/process": ""
+ "symfony/config": "^6.4|^7.0",
+ "symfony/dependency-injection": "^6.4|^7.0",
+ "symfony/event-dispatcher": "^6.4|^7.0",
+ "symfony/http-foundation": "^6.4|^7.0",
+ "symfony/http-kernel": "^6.4|^7.0",
+ "symfony/lock": "^6.4|^7.0",
+ "symfony/messenger": "^6.4|^7.0",
+ "symfony/process": "^6.4|^7.0",
+ "symfony/stopwatch": "^6.4|^7.0",
+ "symfony/var-dumper": "^6.4|^7.0"
},
"type": "library",
"autoload": {
@@ -3038,7 +2924,7 @@
"terminal"
],
"support": {
- "source": "https://github.com/symfony/console/tree/v6.2.8"
+ "source": "https://github.com/symfony/console/tree/v7.2.6"
},
"funding": [
{
@@ -3054,20 +2940,20 @@
"type": "tidelift"
}
],
- "time": "2023-03-29T21:42:15+00:00"
+ "time": "2025-04-07T19:09:28+00:00"
},
{
"name": "symfony/deprecation-contracts",
- "version": "v3.2.1",
+ "version": "v3.5.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
- "reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e"
+ "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e",
- "reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e",
+ "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6",
+ "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6",
"shasum": ""
},
"require": {
@@ -3075,12 +2961,12 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "3.3-dev"
- },
"thanks": {
- "name": "symfony/contracts",
- "url": "https://github.com/symfony/contracts"
+ "url": "https://github.com/symfony/contracts",
+ "name": "symfony/contracts"
+ },
+ "branch-alias": {
+ "dev-main": "3.5-dev"
}
},
"autoload": {
@@ -3105,7 +2991,7 @@
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/deprecation-contracts/tree/v3.2.1"
+ "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1"
},
"funding": [
{
@@ -3121,27 +3007,30 @@
"type": "tidelift"
}
],
- "time": "2023-03-01T10:25:55+00:00"
+ "time": "2024-09-25T14:20:29+00:00"
},
{
"name": "symfony/filesystem",
- "version": "v6.2.7",
+ "version": "v7.2.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
- "reference": "82b6c62b959f642d000456f08c6d219d749215b3"
+ "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/82b6c62b959f642d000456f08c6d219d749215b3",
- "reference": "82b6c62b959f642d000456f08c6d219d749215b3",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/b8dce482de9d7c9fe2891155035a7248ab5c7fdb",
+ "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb",
"shasum": ""
},
"require": {
- "php": ">=8.1",
+ "php": ">=8.2",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-mbstring": "~1.8"
},
+ "require-dev": {
+ "symfony/process": "^6.4|^7.0"
+ },
"type": "library",
"autoload": {
"psr-4": {
@@ -3168,7 +3057,7 @@
"description": "Provides basic utilities for the filesystem",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/filesystem/tree/v6.2.7"
+ "source": "https://github.com/symfony/filesystem/tree/v7.2.0"
},
"funding": [
{
@@ -3184,27 +3073,27 @@
"type": "tidelift"
}
],
- "time": "2023-02-14T08:44:56+00:00"
+ "time": "2024-10-25T15:15:23+00:00"
},
{
"name": "symfony/finder",
- "version": "v6.2.7",
+ "version": "v7.2.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
- "reference": "20808dc6631aecafbe67c186af5dcb370be3a0eb"
+ "reference": "87a71856f2f56e4100373e92529eed3171695cfb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/20808dc6631aecafbe67c186af5dcb370be3a0eb",
- "reference": "20808dc6631aecafbe67c186af5dcb370be3a0eb",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/87a71856f2f56e4100373e92529eed3171695cfb",
+ "reference": "87a71856f2f56e4100373e92529eed3171695cfb",
"shasum": ""
},
"require": {
- "php": ">=8.1"
+ "php": ">=8.2"
},
"require-dev": {
- "symfony/filesystem": "^6.0"
+ "symfony/filesystem": "^6.4|^7.0"
},
"type": "library",
"autoload": {
@@ -3232,7 +3121,7 @@
"description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/finder/tree/v6.2.7"
+ "source": "https://github.com/symfony/finder/tree/v7.2.2"
},
"funding": [
{
@@ -3248,24 +3137,24 @@
"type": "tidelift"
}
],
- "time": "2023-02-16T09:57:23+00:00"
+ "time": "2024-12-30T19:00:17+00:00"
},
{
"name": "symfony/polyfill-ctype",
- "version": "v1.27.0",
+ "version": "v1.32.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "5bbc823adecdae860bb64756d639ecfec17b050a"
+ "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a",
- "reference": "5bbc823adecdae860bb64756d639ecfec17b050a",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638",
+ "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638",
"shasum": ""
},
"require": {
- "php": ">=7.1"
+ "php": ">=7.2"
},
"provide": {
"ext-ctype": "*"
@@ -3275,12 +3164,9 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.27-dev"
- },
"thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
+ "url": "https://github.com/symfony/polyfill",
+ "name": "symfony/polyfill"
}
},
"autoload": {
@@ -3314,7 +3200,7 @@
"portable"
],
"support": {
- "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0"
+ "source": "https://github.com/symfony/polyfill-ctype/tree/v1.32.0"
},
"funding": [
{
@@ -3330,36 +3216,33 @@
"type": "tidelift"
}
],
- "time": "2022-11-03T14:55:06+00:00"
+ "time": "2024-09-09T11:45:10+00:00"
},
{
"name": "symfony/polyfill-intl-grapheme",
- "version": "v1.27.0",
+ "version": "v1.32.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
- "reference": "511a08c03c1960e08a883f4cffcacd219b758354"
+ "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354",
- "reference": "511a08c03c1960e08a883f4cffcacd219b758354",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe",
+ "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe",
"shasum": ""
},
"require": {
- "php": ">=7.1"
+ "php": ">=7.2"
},
"suggest": {
"ext-intl": "For best performance"
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.27-dev"
- },
"thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
+ "url": "https://github.com/symfony/polyfill",
+ "name": "symfony/polyfill"
}
},
"autoload": {
@@ -3395,7 +3278,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0"
+ "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.32.0"
},
"funding": [
{
@@ -3411,36 +3294,33 @@
"type": "tidelift"
}
],
- "time": "2022-11-03T14:55:06+00:00"
+ "time": "2024-09-09T11:45:10+00:00"
},
{
"name": "symfony/polyfill-intl-normalizer",
- "version": "v1.27.0",
+ "version": "v1.32.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
- "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6"
+ "reference": "3833d7255cc303546435cb650316bff708a1c75c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6",
- "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c",
+ "reference": "3833d7255cc303546435cb650316bff708a1c75c",
"shasum": ""
},
"require": {
- "php": ">=7.1"
+ "php": ">=7.2"
},
"suggest": {
"ext-intl": "For best performance"
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.27-dev"
- },
"thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
+ "url": "https://github.com/symfony/polyfill",
+ "name": "symfony/polyfill"
}
},
"autoload": {
@@ -3479,7 +3359,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0"
+ "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.32.0"
},
"funding": [
{
@@ -3495,24 +3375,25 @@
"type": "tidelift"
}
],
- "time": "2022-11-03T14:55:06+00:00"
+ "time": "2024-09-09T11:45:10+00:00"
},
{
"name": "symfony/polyfill-mbstring",
- "version": "v1.27.0",
+ "version": "v1.32.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534"
+ "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
- "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493",
+ "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493",
"shasum": ""
},
"require": {
- "php": ">=7.1"
+ "ext-iconv": "*",
+ "php": ">=7.2"
},
"provide": {
"ext-mbstring": "*"
@@ -3522,12 +3403,9 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.27-dev"
- },
"thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
+ "url": "https://github.com/symfony/polyfill",
+ "name": "symfony/polyfill"
}
},
"autoload": {
@@ -3562,90 +3440,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2022-11-03T14:55:06+00:00"
- },
- {
- "name": "symfony/polyfill-php80",
- "version": "v1.27.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-php80.git",
- "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
- "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "1.27-dev"
- },
- "thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
- }
- },
- "autoload": {
- "files": [
- "bootstrap.php"
- ],
- "psr-4": {
- "Symfony\\Polyfill\\Php80\\": ""
- },
- "classmap": [
- "Resources/stubs"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Ion Bazan",
- "email": "ion.bazan@gmail.com"
- },
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "polyfill",
- "portable",
- "shim"
- ],
- "support": {
- "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0"
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0"
},
"funding": [
{
@@ -3661,24 +3456,24 @@
"type": "tidelift"
}
],
- "time": "2022-11-03T14:55:06+00:00"
+ "time": "2024-12-23T08:48:59+00:00"
},
{
"name": "symfony/process",
- "version": "v6.2.8",
+ "version": "v7.2.5",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
- "reference": "75ed64103df4f6615e15a7fe38b8111099f47416"
+ "reference": "87b7c93e57df9d8e39a093d32587702380ff045d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/75ed64103df4f6615e15a7fe38b8111099f47416",
- "reference": "75ed64103df4f6615e15a7fe38b8111099f47416",
+ "url": "https://api.github.com/repos/symfony/process/zipball/87b7c93e57df9d8e39a093d32587702380ff045d",
+ "reference": "87b7c93e57df9d8e39a093d32587702380ff045d",
"shasum": ""
},
"require": {
- "php": ">=8.1"
+ "php": ">=8.2"
},
"type": "library",
"autoload": {
@@ -3706,7 +3501,7 @@
"description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/process/tree/v6.2.8"
+ "source": "https://github.com/symfony/process/tree/v7.2.5"
},
"funding": [
{
@@ -3722,40 +3517,38 @@
"type": "tidelift"
}
],
- "time": "2023-03-09T16:20:02+00:00"
+ "time": "2025-03-13T12:21:46+00:00"
},
{
"name": "symfony/service-contracts",
- "version": "v3.2.1",
+ "version": "v3.5.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
- "reference": "a8c9cedf55f314f3a186041d19537303766df09a"
+ "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/service-contracts/zipball/a8c9cedf55f314f3a186041d19537303766df09a",
- "reference": "a8c9cedf55f314f3a186041d19537303766df09a",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0",
+ "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0",
"shasum": ""
},
"require": {
"php": ">=8.1",
- "psr/container": "^2.0"
+ "psr/container": "^1.1|^2.0",
+ "symfony/deprecation-contracts": "^2.5|^3"
},
"conflict": {
"ext-psr": "<1.1|>=2"
},
- "suggest": {
- "symfony/service-implementation": ""
- },
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "3.3-dev"
- },
"thanks": {
- "name": "symfony/contracts",
- "url": "https://github.com/symfony/contracts"
+ "url": "https://github.com/symfony/contracts",
+ "name": "symfony/contracts"
+ },
+ "branch-alias": {
+ "dev-main": "3.5-dev"
}
},
"autoload": {
@@ -3791,7 +3584,7 @@
"standards"
],
"support": {
- "source": "https://github.com/symfony/service-contracts/tree/v3.2.1"
+ "source": "https://github.com/symfony/service-contracts/tree/v3.5.1"
},
"funding": [
{
@@ -3807,38 +3600,39 @@
"type": "tidelift"
}
],
- "time": "2023-03-01T10:32:47+00:00"
+ "time": "2024-09-25T14:20:29+00:00"
},
{
"name": "symfony/string",
- "version": "v6.2.8",
+ "version": "v7.2.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
- "reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef"
+ "reference": "a214fe7d62bd4df2a76447c67c6b26e1d5e74931"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/string/zipball/193e83bbd6617d6b2151c37fff10fa7168ebddef",
- "reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef",
+ "url": "https://api.github.com/repos/symfony/string/zipball/a214fe7d62bd4df2a76447c67c6b26e1d5e74931",
+ "reference": "a214fe7d62bd4df2a76447c67c6b26e1d5e74931",
"shasum": ""
},
"require": {
- "php": ">=8.1",
+ "php": ">=8.2",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-intl-grapheme": "~1.0",
"symfony/polyfill-intl-normalizer": "~1.0",
"symfony/polyfill-mbstring": "~1.0"
},
"conflict": {
- "symfony/translation-contracts": "<2.0"
+ "symfony/translation-contracts": "<2.5"
},
"require-dev": {
- "symfony/error-handler": "^5.4|^6.0",
- "symfony/http-client": "^5.4|^6.0",
- "symfony/intl": "^6.2",
- "symfony/translation-contracts": "^2.0|^3.0",
- "symfony/var-exporter": "^5.4|^6.0"
+ "symfony/emoji": "^7.1",
+ "symfony/error-handler": "^6.4|^7.0",
+ "symfony/http-client": "^6.4|^7.0",
+ "symfony/intl": "^6.4|^7.0",
+ "symfony/translation-contracts": "^2.5|^3.0",
+ "symfony/var-exporter": "^6.4|^7.0"
},
"type": "library",
"autoload": {
@@ -3877,7 +3671,7 @@
"utf8"
],
"support": {
- "source": "https://github.com/symfony/string/tree/v6.2.8"
+ "source": "https://github.com/symfony/string/tree/v7.2.6"
},
"funding": [
{
@@ -3893,42 +3687,36 @@
"type": "tidelift"
}
],
- "time": "2023-03-20T16:06:02+00:00"
+ "time": "2025-04-20T20:18:16+00:00"
},
{
"name": "symfony/var-dumper",
- "version": "v5.4.22",
+ "version": "v7.2.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
- "reference": "e2edac9ce47e6df07e38143c7cfa6bdbc1a6dcc4"
+ "reference": "9c46038cd4ed68952166cf7001b54eb539184ccb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/var-dumper/zipball/e2edac9ce47e6df07e38143c7cfa6bdbc1a6dcc4",
- "reference": "e2edac9ce47e6df07e38143c7cfa6bdbc1a6dcc4",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/9c46038cd4ed68952166cf7001b54eb539184ccb",
+ "reference": "9c46038cd4ed68952166cf7001b54eb539184ccb",
"shasum": ""
},
"require": {
- "php": ">=7.2.5",
- "symfony/polyfill-mbstring": "~1.0",
- "symfony/polyfill-php80": "^1.16"
+ "php": ">=8.2",
+ "symfony/polyfill-mbstring": "~1.0"
},
"conflict": {
- "phpunit/phpunit": "<5.4.3",
- "symfony/console": "<4.4"
+ "symfony/console": "<6.4"
},
"require-dev": {
"ext-iconv": "*",
- "symfony/console": "^4.4|^5.0|^6.0",
- "symfony/process": "^4.4|^5.0|^6.0",
- "symfony/uid": "^5.1|^6.0",
- "twig/twig": "^2.13|^3.0.4"
- },
- "suggest": {
- "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).",
- "ext-intl": "To show region name in time zone dump",
- "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script"
+ "symfony/console": "^6.4|^7.0",
+ "symfony/http-kernel": "^6.4|^7.0",
+ "symfony/process": "^6.4|^7.0",
+ "symfony/uid": "^6.4|^7.0",
+ "twig/twig": "^3.12"
},
"bin": [
"Resources/bin/var-dump-server"
@@ -3966,7 +3754,7 @@
"dump"
],
"support": {
- "source": "https://github.com/symfony/var-dumper/tree/v5.4.22"
+ "source": "https://github.com/symfony/var-dumper/tree/v7.2.6"
},
"funding": [
{
@@ -3982,50 +3770,35 @@
"type": "tidelift"
}
],
- "time": "2023-03-25T09:27:28+00:00"
+ "time": "2025-04-09T08:14:01+00:00"
},
{
"name": "thecodingmachine/safe",
- "version": "v2.4.0",
+ "version": "v3.1.1",
"source": {
"type": "git",
"url": "https://github.com/thecodingmachine/safe.git",
- "reference": "e788f3d09dcd36f806350aedb77eac348fafadd3"
+ "reference": "234f6fe34a0bead8c5ae1cfc0800539442e6f619"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thecodingmachine/safe/zipball/e788f3d09dcd36f806350aedb77eac348fafadd3",
- "reference": "e788f3d09dcd36f806350aedb77eac348fafadd3",
+ "url": "https://api.github.com/repos/thecodingmachine/safe/zipball/234f6fe34a0bead8c5ae1cfc0800539442e6f619",
+ "reference": "234f6fe34a0bead8c5ae1cfc0800539442e6f619",
"shasum": ""
},
"require": {
- "php": "^8.0"
+ "php": "^8.1"
},
"require-dev": {
- "phpstan/phpstan": "^1.5",
- "phpunit/phpunit": "^9.5",
- "squizlabs/php_codesniffer": "^3.2",
- "thecodingmachine/phpstan-strict-rules": "^1.0"
+ "php-parallel-lint/php-parallel-lint": "^1.4",
+ "phpstan/phpstan": "^2",
+ "phpunit/phpunit": "^10",
+ "squizlabs/php_codesniffer": "^3.2"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.2.x-dev"
- }
- },
"autoload": {
"files": [
- "deprecated/apc.php",
- "deprecated/array.php",
- "deprecated/datetime.php",
- "deprecated/libevent.php",
- "deprecated/misc.php",
- "deprecated/password.php",
- "deprecated/mssql.php",
- "deprecated/stats.php",
- "deprecated/strings.php",
"lib/special_cases.php",
- "deprecated/mysqli.php",
"generated/apache.php",
"generated/apcu.php",
"generated/array.php",
@@ -4065,6 +3838,7 @@
"generated/mbstring.php",
"generated/misc.php",
"generated/mysql.php",
+ "generated/mysqli.php",
"generated/network.php",
"generated/oci8.php",
"generated/opcache.php",
@@ -4077,6 +3851,7 @@
"generated/ps.php",
"generated/pspell.php",
"generated/readline.php",
+ "generated/rnp.php",
"generated/rpminfo.php",
"generated/rrd.php",
"generated/sem.php",
@@ -4108,7 +3883,6 @@
"lib/DateTime.php",
"lib/DateTimeImmutable.php",
"lib/Exceptions/",
- "deprecated/Exceptions/",
"generated/Exceptions/"
]
},
@@ -4119,22 +3893,36 @@
"description": "PHP core functions that throw exceptions instead of returning FALSE on error",
"support": {
"issues": "https://github.com/thecodingmachine/safe/issues",
- "source": "https://github.com/thecodingmachine/safe/tree/v2.4.0"
+ "source": "https://github.com/thecodingmachine/safe/tree/v3.1.1"
},
- "time": "2022-10-07T14:02:17+00:00"
+ "funding": [
+ {
+ "url": "https://github.com/OskarStark",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/shish",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/staabm",
+ "type": "github"
+ }
+ ],
+ "time": "2025-04-28T07:56:17+00:00"
},
{
"name": "theseer/tokenizer",
- "version": "1.2.1",
+ "version": "1.2.3",
"source": {
"type": "git",
"url": "https://github.com/theseer/tokenizer.git",
- "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e"
+ "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e",
- "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e",
+ "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
+ "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
"shasum": ""
},
"require": {
@@ -4163,7 +3951,7 @@
"description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
"support": {
"issues": "https://github.com/theseer/tokenizer/issues",
- "source": "https://github.com/theseer/tokenizer/tree/1.2.1"
+ "source": "https://github.com/theseer/tokenizer/tree/1.2.3"
},
"funding": [
{
@@ -4171,7 +3959,7 @@
"type": "github"
}
],
- "time": "2021-07-28T10:34:58+00:00"
+ "time": "2024-03-03T12:36:25+00:00"
},
{
"name": "webmozart/assert",
@@ -4234,14 +4022,16 @@
],
"aliases": [],
"minimum-stability": "stable",
- "stability-flags": [],
+ "stability-flags": {
+ "tcds-io/php-better-generics": 20
+ },
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
- "php": ">=8.1",
+ "php": ">=8.4",
"ext-json": "*",
"ext-pdo": "*"
},
- "platform-dev": [],
- "plugin-api-version": "2.3.0"
+ "platform-dev": {},
+ "plugin-api-version": "2.6.0"
}
diff --git a/phpcs.xml b/phpcs.xml
index d16fc82..625dbc4 100644
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -4,91 +4,16 @@
tests
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
error
-
+
+
tests/*
-
+
+
tests/*
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/phpunit.xml b/phpunit.xml
index cae05a7..a3722f2 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -1,24 +1,23 @@
-
-
-
-
- src
-
-
-
+ cacheDirectory=".phpunit.cache"
+ executionOrder="depends,defects"
+ beStrictAboutOutputDuringTests="true"
+ displayDetailsOnPhpunitDeprecations="true"
+ failOnPhpunitDeprecation="true"
+ failOnRisky="true"
+ failOnWarning="true">
-
+
tests
+
+
+ src
+
+
diff --git a/src/Column/BoolColumn.php b/src/Column/BoolColumn.php
new file mode 100644
index 0000000..cc2b8bc
--- /dev/null
+++ b/src/Column/BoolColumn.php
@@ -0,0 +1,24 @@
+
+ */
+readonly class BoolColumn extends Column
+{
+ #[Override] public function plain($entry): ?bool
+ {
+ return parent::plain($entry);
+ }
+
+ #[Override] public function value(array $row): bool
+ {
+ return filter_var(parent::value($row), FILTER_VALIDATE_BOOLEAN);
+ }
+}
diff --git a/src/Column/Column.php b/src/Column/Column.php
index 6dfa6b1..a99131b 100644
--- a/src/Column/Column.php
+++ b/src/Column/Column.php
@@ -6,14 +6,47 @@
use Closure;
-abstract class Column
+/**
+ * @template Entry
+ * @template Value
+ */
+abstract readonly class Column
{
- public readonly string $name;
- public readonly Closure $value;
+ /**
+ * @param Closure(Entry $record): Value $value
+ */
+ public function __construct(
+ public string $name,
+ public Closure $value,
+ ) {
+ }
+
+ /**
+ * @param Entry $entry
+ * @return Value|null
+ */
+ public function plain($entry)
+ {
+ return ($this->value)($entry);
+ }
+
+ /**
+ * @param array $row
+ * @return Value
+ */
+ public function value(array $row)
+ {
+ return $row[$this->name];
+ }
- public function __construct(string $name, Closure $value)
+ /**
+ * @param array $row
+ * @return Value|null
+ */
+ public function nullable(array $row)
{
- $this->name = $name;
- $this->value = $value;
+ return ($row[$this->name] ?? null)
+ ? static::value($row)
+ : null;
}
}
diff --git a/src/Column/DateColumn.php b/src/Column/DateColumn.php
new file mode 100644
index 0000000..3578417
--- /dev/null
+++ b/src/Column/DateColumn.php
@@ -0,0 +1,31 @@
+
+ */
+readonly class DateColumn extends Column
+{
+ public const string FORMAT = 'Y-m-d';
+
+ #[Override] public function plain($entry): ?string
+ {
+ return parent::plain($entry)?->format(self::FORMAT);
+ }
+
+ #[Override] public function value(array $row): DateTime
+ {
+ /** @var string $value */
+ $value = parent::value($row);
+
+ return new DateTime($value);
+ }
+}
diff --git a/src/Column/DateTimeColumn.php b/src/Column/DateTimeColumn.php
new file mode 100644
index 0000000..973d792
--- /dev/null
+++ b/src/Column/DateTimeColumn.php
@@ -0,0 +1,29 @@
+
+ */
+readonly class DateTimeColumn extends Column
+{
+ #[Override] public function plain($entry): ?string
+ {
+ return parent::plain($entry)?->format(DateTimeInterface::ATOM);
+ }
+
+ #[Override] public function value(array $row): DateTime
+ {
+ /** @var string $value */
+ $value = parent::value($row);
+
+ return new DateTime($value);
+ }
+}
diff --git a/src/Column/DateTimeImmutableColumn.php b/src/Column/DateTimeImmutableColumn.php
new file mode 100644
index 0000000..1e20556
--- /dev/null
+++ b/src/Column/DateTimeImmutableColumn.php
@@ -0,0 +1,29 @@
+
+ */
+readonly class DateTimeImmutableColumn extends Column
+{
+ #[Override] public function plain($entry): ?string
+ {
+ return parent::plain($entry)?->format(DateTimeInterface::ATOM);
+ }
+
+ #[Override] public function value(array $row): DateTimeImmutable
+ {
+ /** @var string $value */
+ $value = parent::value($row);
+
+ return new DateTimeImmutable($value);
+ }
+}
diff --git a/src/Column/EnumColumn.php b/src/Column/EnumColumn.php
new file mode 100644
index 0000000..d81ca94
--- /dev/null
+++ b/src/Column/EnumColumn.php
@@ -0,0 +1,41 @@
+
+ */
+readonly class EnumColumn extends Column
+{
+ /**
+ * @param class-string $class
+ */
+ public function __construct(
+ private string $class,
+ string $name,
+ Closure $value,
+ ) {
+ parent::__construct($name, $value);
+ }
+
+ #[Override] public function plain($entry): string|int|null
+ {
+ return parent::plain($entry)?->value;
+ }
+
+ #[Override] public function value(array $row)
+ {
+ /** @var string $value */
+ $value = parent::value($row);
+
+ return $this->class::from($value);
+ }
+}
diff --git a/src/Column/FloatColumn.php b/src/Column/FloatColumn.php
new file mode 100644
index 0000000..8952b90
--- /dev/null
+++ b/src/Column/FloatColumn.php
@@ -0,0 +1,13 @@
+
+ */
+readonly class FloatColumn extends Column
+{
+}
diff --git a/src/Column/IntegerColumn.php b/src/Column/IntegerColumn.php
new file mode 100644
index 0000000..e4e874e
--- /dev/null
+++ b/src/Column/IntegerColumn.php
@@ -0,0 +1,13 @@
+
+ */
+readonly class IntegerColumn extends Column
+{
+}
diff --git a/src/Column/MultiTypeColumn.php b/src/Column/MultiTypeColumn.php
deleted file mode 100644
index f25555d..0000000
--- a/src/Column/MultiTypeColumn.php
+++ /dev/null
@@ -1,9 +0,0 @@
-
+ */
+readonly class StringColumn extends Column
+{
+}
diff --git a/src/Column/TableColumn.php b/src/Column/TableColumn.php
deleted file mode 100644
index 15a3497..0000000
--- a/src/Column/TableColumn.php
+++ /dev/null
@@ -1,18 +0,0 @@
-columns[] = $column;
-
- return $column;
- }
-}
diff --git a/src/Connection/Connection.php b/src/Connection/Connection.php
index b4dc1e0..76f683f 100644
--- a/src/Connection/Connection.php
+++ b/src/Connection/Connection.php
@@ -8,6 +8,8 @@
interface Connection
{
+ public function driver(): ConnectionDriver;
+
public function begin(): void;
public function commit(): void;
@@ -17,12 +19,12 @@ public function rollback(): void;
public function transaction(callable $fn): mixed;
/**
- * @param array $params
+ * @param array $params
*/
public function read(string $statement, array $params = []): PDOStatement;
/**
- * @param array $params
+ * @param array $params
*/
public function write(string $statement, array $params = []): PDOStatement;
}
diff --git a/src/Connection/ConnectionDriver.php b/src/Connection/ConnectionDriver.php
new file mode 100644
index 0000000..e8748b3
--- /dev/null
+++ b/src/Connection/ConnectionDriver.php
@@ -0,0 +1,11 @@
+
+ */
+abstract class EntityRecordMapper extends RecordMapper
+{
+ /** @var Column */
+ public readonly Column $primaryKey;
+
+ /**
+ * @param Column $primaryKey
+ */
+ public function __construct(Column $primaryKey)
+ {
+ $this->primaryKey = $primaryKey;
+ }
+}
diff --git a/src/EntityRecordRepository.php b/src/EntityRecordRepository.php
new file mode 100644
index 0000000..e009a93
--- /dev/null
+++ b/src/EntityRecordRepository.php
@@ -0,0 +1,72 @@
+
+ */
+abstract class EntityRecordRepository extends RecordRepository
+{
+ public function __construct(
+ /** @var EntityRecordMapper */
+ protected EntityRecordMapper $entityMapper,
+ Connection $connection,
+ string $table,
+ ) {
+ parent::__construct($entityMapper, $connection, $table);
+ }
+
+ /**
+ * @param ForeignKeyType $id
+ * @return EntryType|null
+ */
+ public function selectEntityById($id)
+ {
+ return $this->selectOneWhere(['id' => $id]);
+ }
+
+ /**
+ * @param EntryType $entity
+ */
+ public function updateOne($entity): void
+ {
+ $this->updateWhere(
+ $this->mapper->plain($entity),
+ ['id' => $this->entityMapper->primaryKey->plain($entity)],
+ );
+ }
+
+ /**
+ * @param EntryType ...$entities
+ */
+ public function updateMany(...$entities): void
+ {
+ foreach ($entities as $entity) {
+ $this->updateOne($entity);
+ }
+ }
+
+ /**
+ * @param EntryType $entity
+ */
+ public function deleteOne($entity): void
+ {
+ $this->deleteWhere(['id' => $this->entityMapper->primaryKey->plain($entity)]);
+ }
+
+ /**
+ * @param EntryType ...$entities
+ */
+ public function deleteMany(...$entities): void
+ {
+ foreach ($entities as $entity) {
+ $this->deleteOne($entity);
+ }
+ }
+}
diff --git a/src/EntityTable.php b/src/EntityTable.php
deleted file mode 100644
index 0291114..0000000
--- a/src/EntityTable.php
+++ /dev/null
@@ -1,61 +0,0 @@
-
- */
-abstract class EntityTable extends Table
-{
- private Column $primaryKey;
-
- public function __construct(Column $primaryKey, Connection $connection)
- {
- $this->primaryKey = $primaryKey;
-
- parent::__construct($connection);
- }
-
- /**
- * @return T|null
- * @throws Throwable
- */
- public function loadById(int|string $id): ?object
- {
- return $this->loadBy(['id' => $id]);
- }
-
- /**
- * @param T ...$entities
- */
- public function update(object ...$entities): void
- {
- foreach ($entities as $entity) {
- $this->updateWhere(
- array_reduce(
- $this->columns,
- fn($current, Column $column) => array_merge($current, [$column->name => ($column->value)($entity)]),
- [],
- ),
- ['id' => ($this->primaryKey->value)($entity)],
- );
- }
- }
-
- /**
- * @param T ...$entities
- */
- public function delete(object ...$entities): void
- {
- foreach ($entities as $entity) {
- $this->deleteWhere(['id' => ($this->primaryKey->value)($entity)]);
- }
- }
-}
diff --git a/src/RecordMapper.php b/src/RecordMapper.php
new file mode 100644
index 0000000..5251565
--- /dev/null
+++ b/src/RecordMapper.php
@@ -0,0 +1,39 @@
+
+ */
+abstract class RecordMapper extends TableColumn
+{
+ /**
+ * @param array $row
+ * @return T
+ */
+ abstract public function map(array $row);
+
+ /**
+ * @param T $entry
+ * @return array
+ */
+ public function plain($entry): array
+ {
+ $entries = array_map(
+ fn(Column $column) => [$column->name => $column->plain($entry)],
+ $this->columns,
+ );
+
+ return array_merge(...$entries);
+ }
+
+ public function names(): string
+ {
+ return join(', ', array_map(fn(Column $column) => $column->name, $this->columns));
+ }
+}
diff --git a/src/RecordRepository.php b/src/RecordRepository.php
new file mode 100644
index 0000000..31e1b5e
--- /dev/null
+++ b/src/RecordRepository.php
@@ -0,0 +1,168 @@
+ */
+ protected readonly RecordMapper $mapper,
+ protected readonly Connection $connection,
+ protected readonly string $table,
+ ) {
+ }
+
+ /**
+ * @param EntryType $entry
+ */
+ public function insertOne($entry): void
+ {
+ $sql = "INSERT INTO $this->table ({$this->mapper->names()}) VALUES ({$this->bindings()})";
+
+ $values = $this->mapper->plain($entry);
+
+ $this->connection->write($sql, $values);
+ }
+
+ /**
+ * @param array $where
+ * @return EntryType|null
+ */
+ public function selectOneWhere(array $where)
+ {
+ [$whereColumnsString, $whereBindings] = $this->prepareWhere($where);
+ $sql = trim("SELECT * FROM $this->table$whereColumnsString LIMIT 1");
+ $items = $this->connection->read($sql, $whereBindings);
+
+ /** @var array $item */
+ $item = $items->fetch(PDO::FETCH_ASSOC);
+
+ return $item ? $this->mapper->map($item) : null;
+ }
+
+ /**
+ * @param array $bindings
+ * @return EntryType|null
+ */
+ public function selectOneByQuery(string $selectQuery, array $bindings)
+ {
+ $items = $this->connection->read($selectQuery, $bindings);
+
+ /** @var array $item */
+ $item = $items->fetch(PDO::FETCH_ASSOC);
+
+ return $item ? $this->mapper->map($item) : null;
+ }
+
+ /**
+ * @param array $where
+ * @return Traversable
+ */
+ public function selectManyWhere(array $where = [], ?int $limit = null, ?int $offset = null): Traversable
+ {
+ [$whereColumnsString, $whereBindings] = $this->prepareWhere($where);
+ $limitOffset = $this->prepareLimitOffset($limit, $offset);
+ $sql = trim("SELECT * FROM $this->table$whereColumnsString$limitOffset");
+ $items = $this->connection->read($sql, $whereBindings);
+
+ while ($item = $items->fetch(PDO::FETCH_ASSOC)) {
+ /** @var array $item */
+ yield $this->mapper->map($item);
+ }
+ }
+
+ /**
+ * @param array $bindings
+ * @return Traversable
+ */
+ public function selectManyByQuery(string $selectQuery, array $bindings): Traversable
+ {
+ $items = $this->connection->read($selectQuery, $bindings);
+
+ while ($item = $items->fetch(PDO::FETCH_ASSOC)) {
+ /** @var array $item */
+ yield $this->mapper->map($item);
+ }
+ }
+
+ /**
+ * @param array $where
+ */
+ public function existsWhere(array $where): bool
+ {
+ return $this->selectOneWhere($where) !== null;
+ }
+
+ /**
+ * @param array $where
+ */
+ public function deleteWhere(array $where): void
+ {
+ [$whereColumnsString, $whereBindings] = $this->prepareWhere($where);
+ $sql = trim("DELETE FROM $this->table$whereColumnsString");
+
+ $this->connection->write($sql, $whereBindings);
+ }
+
+ /**
+ * @param array $values
+ * @param array $where
+ */
+ public function updateWhere(array $values, array $where): void
+ {
+ $columnBindings = [];
+ $valuesBinding = [];
+
+ foreach ($values as $column => $value) {
+ $columnBindings[] = "$column = :$column";
+ $valuesBinding[$column] = $value;
+ }
+
+ $columnBindingsString = join(", ", $columnBindings);
+
+ [$whereColumnsString, $whereBindings] = $this->prepareWhere($where);
+ $sql = trim("UPDATE $this->table SET $columnBindingsString$whereColumnsString");
+
+ $this->connection->write($sql, array_merge($valuesBinding, $whereBindings));
+ }
+
+ private function bindings(): string
+ {
+ return join(', ', array_map(fn(Column $column) => ":$column->name", $this->mapper->columns));
+ }
+
+ /**
+ * @param array $where
+ * @return array{0: string, 1: array}
+ */
+ private function prepareWhere(array $where): array
+ {
+ $whereColumns = [];
+ $whereBindings = [];
+
+ foreach ($where as $column => $value) {
+ $whereColumns[] = "$column = :$column";
+ $whereBindings[$column] = $value;
+ }
+
+ return [
+ empty($whereColumns) ? '' : sprintf(" WHERE %s", join(' AND ', $whereColumns)),
+ $whereBindings,
+ ];
+ }
+
+ private function prepareLimitOffset(?int $limit, ?int $offset): string
+ {
+ return ($limit ? " LIMIT $limit" : '') . ($offset ? " OFFSET $offset" : '');
+ }
+}
diff --git a/src/Table.php b/src/Table.php
deleted file mode 100644
index e343590..0000000
--- a/src/Table.php
+++ /dev/null
@@ -1,204 +0,0 @@
- */
- protected array $columns = [];
- protected Connection $connection;
-
- abstract public function name(): string;
-
- /**
- * @param array $row
- * @return T
- */
- abstract public function entry(array $row);
-
- public function __construct(Connection $connection)
- {
- $this->connection = $connection;
- }
-
- /**
- * @param T $entry
- */
- public function insert(object $entry): void
- {
- $sql = "INSERT INTO {$this->name()} ({$this->columnNames()}) VALUES ({$this->columnBindings()})";
-
- $values = $this->valuesOf($entry);
-
- $this->connection->write($sql, $values);
- }
-
- /**
- * @param array $where
- * @return T|null
- * @throws Throwable
- */
- public function loadBy(array $where): ?object
- {
- [$whereColumnsString, $whereBindings] = $this->prepareWhere($where);
- $sql = trim("SELECT * FROM {$this->name()}$whereColumnsString LIMIT 1");
- $items = $this->connection->read($sql, $whereBindings);
-
- /** @var array $item */
- $item = $items->fetch(PDO::FETCH_ASSOC);
-
- return $item ? $this->entry($item) : null;
- }
-
- /**
- * @param array $bindings
- * @return T|null
- * @throws Throwable
- */
- public function loadByQuery(string $selectQuery, array $bindings): ?object
- {
- $items = $this->connection->read($selectQuery, $bindings);
-
- /** @var array $item */
- $item = $items->fetch(PDO::FETCH_ASSOC);
-
- return $item ? $this->entry($item) : null;
- }
-
- /**
- * @param array $where
- * @return Traversable
- */
- public function findBy(array $where, ?int $limit = null, ?int $offset = null): Traversable
- {
- [$whereColumnsString, $whereBindings] = $this->prepareWhere($where);
- $limitOffset = $this->prepareLimitOffset($limit, $offset);
- $sql = trim("SELECT * FROM {$this->name()}{$whereColumnsString}{$limitOffset}");
- $items = $this->connection->read($sql, $whereBindings);
-
- while ($item = $items->fetch(PDO::FETCH_ASSOC)) {
- /** @var array $item */
- yield $this->entry($item);
- }
- }
-
- /**
- * @param array $bindings
- * @return Traversable
- */
- public function findByQuery(string $selectQuery, array $bindings): Traversable
- {
- $items = $this->connection->read($selectQuery, $bindings);
-
- while ($item = $items->fetch(PDO::FETCH_ASSOC)) {
- /** @var array $item */
- yield $this->entry($item);
- }
- }
-
- /**
- * @param array $where
- */
- public function deleteWhere(array $where): void
- {
- [$whereColumnsString, $whereBindings] = $this->prepareWhere($where);
- $sql = trim("DELETE FROM {$this->name()}$whereColumnsString");
-
- $this->connection->write($sql, $whereBindings);
- }
-
- /**
- * @param array $where
- * @throws Throwable
- */
- public function exists(array $where): bool
- {
- return $this->loadBy($where) !== null;
- }
-
- /**
- * @param array $values
- * @param array $where
- */
- public function updateWhere(array $values, array $where): void
- {
- $columnBindings = [];
- $valuesBinding = [];
-
- foreach ($values as $column => $value) {
- $key = ":$column";
- $columnBindings[] = "$column = $key";
- $valuesBinding[$key] = $value;
- }
-
- $columnBindingsString = join(", ", $columnBindings);
-
- [$whereColumnsString, $whereBindings] = $this->prepareWhere($where);
- $sql = trim("UPDATE {$this->name()} SET {$columnBindingsString}{$whereColumnsString}");
-
- $this->connection->write($sql, array_merge($valuesBinding, $whereBindings));
- }
-
- /**
- * @param T $entry
- * @return array
- */
- public function valuesOf(object $entry): array
- {
- return array_reduce(
- $this->columns,
- fn($current, Column $column) => array_merge($current, ["$column->name" => ($column->value)($entry)]),
- [],
- );
- }
-
- private function columnNames(): string
- {
- return join(', ', array_map(fn(Column $column) => $column->name, $this->columns));
- }
-
- private function columnBindings(): string
- {
- return join(', ', array_map(fn(Column $column) => ":$column->name", $this->columns));
- }
-
- /**
- * @param array $where
- * @return array{0: string, 1: array}
- */
- private function prepareWhere(array $where): array
- {
- $whereColumns = [];
- $whereBindings = [];
-
- foreach ($where as $column => $value) {
- $binding = ":$column";
- $whereColumns[] = "$column = $binding";
- $whereBindings[$binding] = $value;
- }
-
- return [
- empty($whereColumns) ? '' : sprintf(" WHERE %s", join(' AND ', $whereColumns)),
- $whereBindings,
- ];
- }
-
- private function prepareLimitOffset(?int $limit, ?int $offset): string
- {
- return ($limit ? " LIMIT $limit" : '') . ($offset ? " OFFSET $offset" : '');
- }
-}
diff --git a/src/TableColumn.php b/src/TableColumn.php
new file mode 100644
index 0000000..b25fad8
--- /dev/null
+++ b/src/TableColumn.php
@@ -0,0 +1,125 @@
+> */
+ public private(set) array $columns = [];
+
+ /**
+ * @param Closure(EntryType $entry): string $value
+ * @return StringColumn
+ */
+ protected function string(string $name, Closure $value): StringColumn
+ {
+ $column = new StringColumn($name, $value);
+ $this->columns[] = $column;
+
+ return $column;
+ }
+
+ /**
+ * @param Closure(EntryType $entry): bool $value
+ * @return BoolColumn
+ */
+ protected function boolean(string $name, Closure $value): BoolColumn
+ {
+ $column = new BoolColumn($name, $value);
+ $this->columns[] = $column;
+
+ return $column;
+ }
+
+ /**
+ * @param Closure(EntryType $entry): float $value
+ * @return FloatColumn
+ */
+ protected function numeric(string $name, Closure $value): FloatColumn
+ {
+ $column = new FloatColumn($name, $value);
+ $this->columns[] = $column;
+
+ return $column;
+ }
+
+ /**
+ * @param Closure(EntryType $entry): int $value
+ * @return IntegerColumn
+ */
+ protected function integer(string $name, Closure $value): IntegerColumn
+ {
+ $column = new IntegerColumn($name, $value);
+ $this->columns[] = $column;
+
+ return $column;
+ }
+
+ /**
+ * @param Closure(EntryType $entry): DateTimeInterface $value
+ * @return DateColumn
+ */
+ protected function date(string $name, Closure $value): DateColumn
+ {
+ $column = new DateColumn($name, $value);
+ $this->columns[] = $column;
+
+ return $column;
+ }
+
+ /**
+ * @param Closure(EntryType $entry): DateTimeInterface $value
+ * @return DateTimeColumn
+ */
+ protected function datetime(string $name, Closure $value): DateTimeColumn
+ {
+ $column = new DateTimeColumn($name, $value);
+ $this->columns[] = $column;
+
+ return $column;
+ }
+
+ /**
+ * @param Closure(EntryType $entry): DateTimeInterface $value
+ * @return DateTimeImmutableColumn
+ */
+ protected function datetimeImmutable(string $name, Closure $value): DateTimeImmutableColumn
+ {
+ $column = new DateTimeImmutableColumn($name, $value);
+ $this->columns[] = $column;
+
+ return $column;
+ }
+
+ /**
+ * @template EnumType of BackedEnum
+ * @param class-string $class
+ * @param Closure(EntryType $entry): EnumType $value
+ * @return EnumColumn
+ */
+ protected function enum(string $class, string $name, Closure $value): EnumColumn
+ {
+ $column = new EnumColumn($class, $name, $value);
+ $this->columns[] = $column;
+
+ return $column;
+ }
+}
diff --git a/tests/Fixtures/Address.php b/tests/Fixtures/Address.php
index a2d68b1..6d8e847 100644
--- a/tests/Fixtures/Address.php
+++ b/tests/Fixtures/Address.php
@@ -4,14 +4,82 @@
namespace Test\Tcds\Io\Orm\Fixtures;
-class Address
+use DateTime;
+use DateTimeImmutable;
+
+readonly class Address
{
- public readonly string $id;
- public readonly string $street;
+ public function __construct(
+ public int $id,
+ public string $street,
+ public float $number,
+ public int $floor,
+ public bool $active,
+ public AddressType $type,
+ public DateTime $createdAt,
+ public ?DateTimeImmutable $deletedAt,
+ ) {
+ }
+
+ public static function first(): self
+ {
+ return new self(
+ id: 1,
+ street: 'First Avenue',
+ number: 145.45,
+ floor: 1,
+ active: true,
+ type: AddressType::RESIDENCE,
+ createdAt: new DateTime('2025-05-01 10:15:20'),
+ deletedAt: new DateTimeImmutable('2025-05-10 11:16:30'),
+ );
+ }
+
+ public static function second(): self
+ {
+ return new self(
+ id: 2,
+ street: 'Second Avenue',
+ number: 34.90,
+ floor: 5,
+ active: false,
+ type: AddressType::WORK,
+ createdAt: new DateTime('2025-05-02 20:25:30'),
+ deletedAt: null,
+ );
+ }
+
+ /**
+ * @return array
+ */
+ public static function firstRowData(): array
+ {
+ return [
+ 'id' => 1,
+ 'street' => 'First Avenue',
+ 'number' => 145.45,
+ 'floor' => 1,
+ 'active' => true,
+ 'type' => 'RESIDENCE',
+ 'created_at' => '2025-05-01T10:15:20+00:00',
+ 'deleted_at' => '2025-05-10T11:16:30+00:00',
+ ];
+ }
- public function __construct(string $id, string $street)
+ /**
+ * @return array
+ */
+ public static function secondRowData(): array
{
- $this->id = $id;
- $this->street = $street;
+ return [
+ 'id' => 2,
+ 'street' => 'Second Avenue',
+ 'number' => 34.90,
+ 'floor' => 5,
+ 'active' => false,
+ 'type' => 'WORK',
+ 'created_at' => '2025-05-02T20:25:30+00:00',
+ 'deleted_at' => null,
+ ];
}
}
diff --git a/tests/Fixtures/AddressEntityTable.php b/tests/Fixtures/AddressEntityTable.php
deleted file mode 100644
index 25a9a6a..0000000
--- a/tests/Fixtures/AddressEntityTable.php
+++ /dev/null
@@ -1,34 +0,0 @@
-column('street', fn(Address $entity) => $entity->street);
-
- parent::__construct($this->column('id', fn(Address $entity) => $entity->id), $connection);
- }
-
- public function name(): string
- {
- return "addresses";
- }
-
- /**
- * @param array $row
- */
- public function entry(array $row): Address
- {
- return new Address(
- id: $row['id'],
- street: $row['street'],
- );
- }
-}
diff --git a/tests/Fixtures/AddressMapper.php b/tests/Fixtures/AddressMapper.php
new file mode 100644
index 0000000..b820478
--- /dev/null
+++ b/tests/Fixtures/AddressMapper.php
@@ -0,0 +1,55 @@
+id = $this->integer('id', fn(Address $entry) => $entry->id);
+ $this->street = $this->string('street', fn(Address $entity) => $entity->street);
+ $this->number = $this->numeric('number', fn(Address $entity) => $entity->number);
+ $this->floor = $this->integer('floor', fn(Address $entity) => $entity->floor);
+ $this->active = $this->boolean('active', fn(Address $entity) => $entity->active);
+ $this->type = $this->enum(AddressType::class, 'type', fn(Address $entity) => $entity->type);
+ $this->createdAt = $this->datetime('created_at', fn(Address $entity) => $entity->createdAt);
+ $this->deletedAt = $this->datetimeImmutable('deleted_at', fn(Address $entity) => $entity->deletedAt);
+ }
+
+ /**
+ * @param array $row
+ */
+ public function map(array $row): Address
+ {
+ return new Address(
+ id: $this->id->value($row),
+ street: $this->street->value($row),
+ number: $this->number->value($row),
+ floor: $this->floor->value($row),
+ active: $this->active->value($row),
+ type: $this->type->value($row),
+ createdAt: $this->createdAt->value($row),
+ deletedAt: $this->deletedAt->nullable($row),
+ );
+ }
+}
diff --git a/tests/Fixtures/AddressRepository.php b/tests/Fixtures/AddressRepository.php
new file mode 100644
index 0000000..1ccfb65
--- /dev/null
+++ b/tests/Fixtures/AddressRepository.php
@@ -0,0 +1,26 @@
+
+ */
+class AddressRepository extends RecordRepository
+{
+ public function __construct(Connection $connection, RecordMapper $mapper)
+ {
+ parent::__construct($mapper, $connection, 'addresses');
+ }
+
+ public function loadById(int $id): Address
+ {
+ return $this->selectOneWhere(['id' => $id]) ?? throw new Exception('Address not found');
+ }
+}
diff --git a/tests/Fixtures/AddressTable.php b/tests/Fixtures/AddressTable.php
deleted file mode 100644
index 88e3a7f..0000000
--- a/tests/Fixtures/AddressTable.php
+++ /dev/null
@@ -1,38 +0,0 @@
-column("id", fn(Address $entity) => $entity->id);
- $this->column("street", fn(Address $entity) => $entity->street);
-
- parent::__construct($connection);
- }
-
- public function name(): string
- {
- return "addresses";
- }
-
- /**
- * @param array $row
- */
- public function entry(array $row): Address
- {
- return new Address(
- id: $row['id'],
- street: $row['street'],
- );
- }
-}
diff --git a/tests/Fixtures/AddressType.php b/tests/Fixtures/AddressType.php
new file mode 100644
index 0000000..5a2b1f9
--- /dev/null
+++ b/tests/Fixtures/AddressType.php
@@ -0,0 +1,11 @@
+
+ */
+ public static function firstData(): array
+ {
+ return [
+ 'id' => 1,
+ 'name' => 'First User',
+ 'date_of_birth' => '2020-01-01',
+ 'address_id' => 1,
+ ];
+ }
+
+ /**
+ * @return array
+ */
+ public static function secondData(): array
+ {
+ return [
+ 'id' => 2,
+ 'name' => 'Second User',
+ 'date_of_birth' => '2022-10-15',
+ 'address_id' => 2,
+ ];
+ }
+}
diff --git a/tests/Fixtures/UserMapper.php b/tests/Fixtures/UserMapper.php
new file mode 100644
index 0000000..56d94a8
--- /dev/null
+++ b/tests/Fixtures/UserMapper.php
@@ -0,0 +1,35 @@
+
+ */
+final class UserMapper extends EntityRecordMapper
+{
+ public function __construct(
+ private readonly AddressRepository $addressRepository,
+ ) {
+ parent::__construct($this->string('id', fn(User $entity) => $entity->id));
+
+ $this->string('name', fn(User $entity) => $entity->name);
+ $this->date('date_of_birth', fn(User $entity) => $entity->dateOfBirth);
+ $this->integer('address_id', fn(User $entity) => $entity->address->id);
+ }
+
+ #[Override] public function map(array $row): User
+ {
+ return new User(
+ id: $row['id'],
+ name: $row['name'],
+ dateOfBirth: new DateTime($row['date_of_birth']),
+ address: lazyOf(Address::class, fn() => $this->addressRepository->loadById($row['address_id'])),
+ );
+ }
+}
diff --git a/tests/Fixtures/UserRepository.php b/tests/Fixtures/UserRepository.php
new file mode 100644
index 0000000..7425d96
--- /dev/null
+++ b/tests/Fixtures/UserRepository.php
@@ -0,0 +1,25 @@
+
+ */
+class UserRepository extends EntityRecordRepository
+{
+ public function __construct(Connection $connection, UserMapper $mapper)
+ {
+ parent::__construct($mapper, $connection, 'users');
+ }
+
+ public function loadById(string $id): User
+ {
+ return $this->selectEntityById($id) ?? throw new Exception('Address not found');
+ }
+}
diff --git a/tests/TestCase.php b/tests/TestCase.php
new file mode 100644
index 0000000..2cc0a73
--- /dev/null
+++ b/tests/TestCase.php
@@ -0,0 +1,28 @@
+ ...$expectedCalls
+ */
+ public function consecutive(InvokedCountMatcher $matcher, array ...$expectedCalls): Callback
+ {
+ $expectedCalls = array_values($expectedCalls);
+
+ return $this->callback(function (...$args) use ($matcher, $expectedCalls) {
+ $index = $matcher->numberOfInvocations() - 1;
+
+ $this->assertEquals($expectedCalls[$index], $args);
+
+ return true;
+ });
+ }
+}
diff --git a/tests/Unit/Column/BoolColumnTest.php b/tests/Unit/Column/BoolColumnTest.php
new file mode 100644
index 0000000..1d80c97
--- /dev/null
+++ b/tests/Unit/Column/BoolColumnTest.php
@@ -0,0 +1,40 @@
+column = new BoolColumn('active', fn(object $entry) => $entry->active);
+ }
+
+ #[Test] public function given_an_entry_then_get_its_plain_value(): void
+ {
+ $this->assertTrue($this->column->plain((object) ['active' => true]));
+ $this->assertFalse($this->column->plain((object) ['active' => false]));
+ }
+
+ #[Test] public function given_an_array_then_get_its_value(): void
+ {
+ $this->assertTrue($this->column->value(['active' => true]));
+ $this->assertFalse($this->column->value(['active' => false]));
+
+ $this->assertTrue($this->column->value(['active' => 'true']));
+ $this->assertFalse($this->column->value(['active' => 'false']));
+
+ $this->assertTrue($this->column->value(['active' => 1]));
+ $this->assertFalse($this->column->value(['active' => 0]));
+
+ $this->assertTrue($this->column->value(['active' => '1']));
+ $this->assertFalse($this->column->value(['active' => '0']));
+ }
+}
diff --git a/tests/Unit/Column/ColumnTest.php b/tests/Unit/Column/ColumnTest.php
new file mode 100644
index 0000000..b7975ca
--- /dev/null
+++ b/tests/Unit/Column/ColumnTest.php
@@ -0,0 +1,42 @@
+column = new readonly class ('prop', fn(object $entry) => $entry->prop) extends Column
+ {
+ #[Override] public function value(array $row): string
+ {
+ return parent::value($row) . '-' . parent::value($row);
+ }
+ };
+ }
+
+ #[Test] public function given_row_when_prop_is_not_null_then_return_value(): void
+ {
+ $this->assertEquals('bar-bar', $this->column->nullable(['prop' => 'bar']));
+ }
+
+ #[Test] public function given_row_when_prop_is_null_then_return_null(): void
+ {
+ $this->assertNull($this->column->nullable(['prop' => null]));
+ }
+
+ #[Test] public function given_row_when_prop_is_unset_null_then_return_null(): void
+ {
+ $this->assertNull($this->column->nullable([]));
+ }
+}
diff --git a/tests/Unit/Column/DateColumnTest.php b/tests/Unit/Column/DateColumnTest.php
new file mode 100644
index 0000000..d577cdb
--- /dev/null
+++ b/tests/Unit/Column/DateColumnTest.php
@@ -0,0 +1,48 @@
+column = new DateColumn('created_at', fn(object $entry) => $entry->created_at);
+ }
+
+ #[Test] public function given_an_entry_then_get_its_plain_value(): void
+ {
+ $entry = (object) ['created_at' => new DateTime('2025-05-08')];
+
+ $plain = $this->column->plain($entry);
+
+ $this->assertEquals('2025-05-08', $plain);
+ }
+
+ #[Test] public function given_an_entry_when_value_is_null_then_get_null(): void
+ {
+ $entry = (object) ['created_at' => null];
+
+ $plain = $this->column->plain($entry);
+
+ $this->assertNull($plain);
+ }
+
+ #[Test] public function given_an_array_then_get_its_value(): void
+ {
+ $row = ['created_at' => '2025-05-08'];
+
+ $value = $this->column->value($row);
+
+ $this->assertEquals(DateTime::class, $value::class);
+ $this->assertEquals(new DateTime('2025-05-08'), $value);
+ }
+}
diff --git a/tests/Unit/Column/DateTimeColumnTest.php b/tests/Unit/Column/DateTimeColumnTest.php
new file mode 100644
index 0000000..71c558b
--- /dev/null
+++ b/tests/Unit/Column/DateTimeColumnTest.php
@@ -0,0 +1,48 @@
+column = new DateTimeColumn('created_at', fn(object $entry) => $entry->created_at);
+ }
+
+ #[Test] public function given_an_entry_then_get_its_plain_value(): void
+ {
+ $entry = (object) ['created_at' => new DateTime('2025-05-08T18:46:20')];
+
+ $plain = $this->column->plain($entry);
+
+ $this->assertEquals('2025-05-08T18:46:20+00:00', $plain);
+ }
+
+ #[Test] public function given_an_entry_when_value_is_null_then_get_null(): void
+ {
+ $entry = (object) ['created_at' => null];
+
+ $plain = $this->column->plain($entry);
+
+ $this->assertNull($plain);
+ }
+
+ #[Test] public function given_an_array_then_get_its_value(): void
+ {
+ $row = ['created_at' => '2025-05-08T18:46:20'];
+
+ $value = $this->column->value($row);
+
+ $this->assertEquals(DateTime::class, $value::class);
+ $this->assertEquals(new DateTime('2025-05-08T18:46:20'), $value);
+ }
+}
diff --git a/tests/Unit/Column/DateTimeImmutableColumnTest.php b/tests/Unit/Column/DateTimeImmutableColumnTest.php
new file mode 100644
index 0000000..258d779
--- /dev/null
+++ b/tests/Unit/Column/DateTimeImmutableColumnTest.php
@@ -0,0 +1,48 @@
+column = new DateTimeImmutableColumn('created_at', fn(object $entry) => $entry->created_at);
+ }
+
+ #[Test] public function given_an_entry_then_get_its_plain_value(): void
+ {
+ $entry = (object) ['created_at' => new DateTimeImmutable('2025-05-08T18:46:20')];
+
+ $plain = $this->column->plain($entry);
+
+ $this->assertEquals('2025-05-08T18:46:20+00:00', $plain);
+ }
+
+ #[Test] public function given_an_entry_when_value_is_null_then_get_null(): void
+ {
+ $entry = (object) ['created_at' => null];
+
+ $plain = $this->column->plain($entry);
+
+ $this->assertNull($plain);
+ }
+
+ #[Test] public function given_an_array_then_get_its_value(): void
+ {
+ $row = ['created_at' => '2025-05-08T18:46:20'];
+
+ $value = $this->column->value($row);
+
+ $this->assertEquals(DateTimeImmutable::class, $value::class);
+ $this->assertEquals(new DateTimeImmutable('2025-05-08T18:46:20'), $value);
+ }
+}
diff --git a/tests/Unit/Column/EnumColumnTest.php b/tests/Unit/Column/EnumColumnTest.php
new file mode 100644
index 0000000..ef1af00
--- /dev/null
+++ b/tests/Unit/Column/EnumColumnTest.php
@@ -0,0 +1,47 @@
+column = new EnumColumn(AddressType::class, 'type', fn(object $entry) => $entry->type);
+ }
+
+ #[Test] public function given_an_entry_then_get_its_plain_value(): void
+ {
+ $entry = (object) ['type' => AddressType::RESIDENCE];
+
+ $plain = $this->column->plain($entry);
+
+ $this->assertEquals('RESIDENCE', $plain);
+ }
+
+ #[Test] public function given_an_entry_when_value_is_null_then_get_null(): void
+ {
+ $entry = (object) ['type' => null];
+
+ $plain = $this->column->plain($entry);
+
+ $this->assertNull($plain);
+ }
+
+ #[Test] public function given_an_array_then_get_its_value(): void
+ {
+ $row = ['type' => 'RESIDENCE'];
+
+ $value = $this->column->value($row);
+
+ $this->assertEquals(AddressType::RESIDENCE, $value);
+ }
+}
diff --git a/tests/Unit/Column/FloatColumnTest.php b/tests/Unit/Column/FloatColumnTest.php
new file mode 100644
index 0000000..19f8eff
--- /dev/null
+++ b/tests/Unit/Column/FloatColumnTest.php
@@ -0,0 +1,37 @@
+column = new FloatColumn('height', fn(object $entry) => $entry->height);
+ }
+
+ #[Test] public function given_an_entry_then_get_its_plain_value(): void
+ {
+ $entry = (object) ['height' => 1.76];
+
+ $plain = $this->column->plain($entry);
+
+ $this->assertEquals(1.76, $plain);
+ }
+
+ #[Test] public function given_an_array_then_get_its_value(): void
+ {
+ $row = ['height' => 1.76];
+
+ $value = $this->column->value($row);
+
+ $this->assertEquals(1.76, $value);
+ }
+}
diff --git a/tests/Unit/Column/IntegerColumnTest.php b/tests/Unit/Column/IntegerColumnTest.php
new file mode 100644
index 0000000..2c404c9
--- /dev/null
+++ b/tests/Unit/Column/IntegerColumnTest.php
@@ -0,0 +1,37 @@
+column = new IntegerColumn('age', fn(object $entry) => $entry->age);
+ }
+
+ #[Test] public function given_an_entry_then_get_its_plain_value(): void
+ {
+ $entry = (object) ['age' => 36];
+
+ $plain = $this->column->plain($entry);
+
+ $this->assertEquals(36, $plain);
+ }
+
+ #[Test] public function given_an_array_then_get_its_value(): void
+ {
+ $row = ['age' => 36];
+
+ $value = $this->column->value($row);
+
+ $this->assertEquals(36, $value);
+ }
+}
diff --git a/tests/Unit/Column/StringColumnTest.php b/tests/Unit/Column/StringColumnTest.php
new file mode 100644
index 0000000..8d9b47c
--- /dev/null
+++ b/tests/Unit/Column/StringColumnTest.php
@@ -0,0 +1,37 @@
+column = new StringColumn('name', fn(object $entry) => $entry->name);
+ }
+
+ #[Test] public function given_an_entry_then_get_its_plain_value(): void
+ {
+ $entry = (object) ['name' => 'Arthur Dent'];
+
+ $plain = $this->column->plain($entry);
+
+ $this->assertEquals('Arthur Dent', $plain);
+ }
+
+ #[Test] public function given_an_array_then_get_its_value(): void
+ {
+ $row = ['name' => 'Arthur Dent'];
+
+ $value = $this->column->value($row);
+
+ $this->assertEquals('Arthur Dent', $value);
+ }
+}
diff --git a/tests/Unit/Connection/Pdo/GenericConnectionTest.php b/tests/Unit/Connection/Pdo/GenericConnectionTest.php
index cfa3b51..2cbe987 100644
--- a/tests/Unit/Connection/Pdo/GenericConnectionTest.php
+++ b/tests/Unit/Connection/Pdo/GenericConnectionTest.php
@@ -8,8 +8,9 @@
use PDO;
use PDOStatement;
use PHPUnit\Framework\MockObject\MockObject;
-use PHPUnit\Framework\TestCase;
+use Tcds\Io\Orm\Connection\ConnectionDriver;
use Tcds\Io\Orm\Connection\Pdo\GenericConnection;
+use Test\Tcds\Io\Orm\TestCase;
class GenericConnectionTest extends TestCase
{
@@ -25,27 +26,27 @@ protected function setUp(): void
$this->write = $this->createMock(PDO::class);
$this->statement = $this->createMock(PDOStatement::class);
- $this->connection = new GenericConnection($this->read, $this->write);
+ $this->connection = new class ($this->read, $this->write) extends GenericConnection
+ {
+ public function driver(): ConnectionDriver
+ {
+ return ConnectionDriver::GENERIC;
+ }
+ };
}
public function testGivenPdoThenConfigurePdo(): void
{
- $this->read
- ->expects($this->exactly(2))
- ->method('setAttribute')
- ->withConsecutive(
- [PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION],
- [PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC],
- );
- $this->write
- ->expects($this->exactly(2))
- ->method('setAttribute')
- ->withConsecutive(
- [PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION],
- [PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC],
- );
-
- new GenericConnection($this->read, $this->write);
+ $this->expectToSetupPdo($this->read);
+ $this->expectToSetupPdo($this->write);
+
+ new class ($this->read, $this->write) extends GenericConnection
+ {
+ public function driver(): ConnectionDriver
+ {
+ return ConnectionDriver::GENERIC;
+ }
+ };
}
public function testGivenTheQueryAndItsParamsWhenExecuteIsCalledThenRunPrepareAndExecuteInPdo(): void
@@ -132,4 +133,18 @@ public function testWhenTransactionSucceedThenCommitAndReturnCallbackResponse():
$this->assertEquals("success", $response);
}
+
+ private function expectToSetupPdo(PDO&MockObject $pdo): void
+ {
+ $matcher = $this->exactly(2);
+
+ $pdo
+ ->expects($matcher)
+ ->method('setAttribute')
+ ->with($this->consecutive(
+ matcher: $matcher,
+ first: [PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION],
+ second: [PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC],
+ ));
+ }
}
diff --git a/tests/Unit/Connection/Pdo/MysqlConnectionTest.php b/tests/Unit/Connection/Pdo/MysqlConnectionTest.php
index 82d25b5..12ecf9c 100644
--- a/tests/Unit/Connection/Pdo/MysqlConnectionTest.php
+++ b/tests/Unit/Connection/Pdo/MysqlConnectionTest.php
@@ -5,8 +5,9 @@
namespace Test\Tcds\Io\Orm\Unit\Connection\Pdo;
use PDO;
-use PHPUnit\Framework\TestCase;
+use PHPUnit\Framework\MockObject\MockObject;
use Tcds\Io\Orm\Connection\Pdo\MysqlConnection;
+use Test\Tcds\Io\Orm\TestCase;
class MysqlConnectionTest extends TestCase
{
@@ -15,22 +16,24 @@ public function testGivenPdoThenConfigurePdoWithMysqlInitCommand(): void
$read = $this->createMock(PDO::class);
$write = $this->createMock(PDO::class);
- $read->expects($this->exactly(3))
- ->method('setAttribute')
- ->withConsecutive(
- [PDO::MYSQL_ATTR_INIT_COMMAND, 'SET NAMES utf8'],
- [PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION],
- [PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC],
- );
-
- $write->expects($this->exactly(3))
- ->method('setAttribute')
- ->withConsecutive(
- [PDO::MYSQL_ATTR_INIT_COMMAND, 'SET NAMES utf8'],
- [PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION],
- [PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC],
- );
+ $this->expectToSetupPdo($read);
+ $this->expectToSetupPdo($write);
new MysqlConnection($read, $write);
}
+
+ private function expectToSetupPdo(PDO&MockObject $pdo): void
+ {
+ $matcher = $this->exactly(3);
+
+ $pdo
+ ->expects($matcher)
+ ->method('setAttribute')
+ ->with($this->consecutive(
+ matcher: $matcher,
+ first: [PDO::MYSQL_ATTR_INIT_COMMAND, 'SET NAMES utf8'],
+ second: [PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION],
+ third: [PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC],
+ ));
+ }
}
diff --git a/tests/Unit/Connection/Pdo/NestedTransactionConnectionTest.php b/tests/Unit/Connection/Pdo/NestedTransactionConnectionTest.php
index 1db04a2..7a26653 100644
--- a/tests/Unit/Connection/Pdo/NestedTransactionConnectionTest.php
+++ b/tests/Unit/Connection/Pdo/NestedTransactionConnectionTest.php
@@ -7,8 +7,9 @@
use PDO;
use PDOException;
use PHPUnit\Framework\MockObject\MockObject;
-use PHPUnit\Framework\TestCase;
+use Tcds\Io\Orm\Connection\ConnectionDriver;
use Tcds\Io\Orm\Connection\Pdo\NestedTransactionConnection;
+use Test\Tcds\Io\Orm\TestCase;
class NestedTransactionConnectionTest extends TestCase
{
@@ -21,16 +22,22 @@ protected function setUp(): void
$read = $this->createMock(PDO::class);
$this->write = $this->createMock(PDO::class);
- $this->connection = new NestedTransactionConnection($read, $this->write);
+ $this->connection = new class ($read, $this->write) extends NestedTransactionConnection
+ {
+ public function driver(): ConnectionDriver
+ {
+ return ConnectionDriver::GENERIC;
+ }
+ };
}
public function testWhenBeginThenCommitGetsCalledThenRunBeginAndCommitStatements(): void
{
- $this->write->expects($this->exactly(2))->method('exec')
- ->withConsecutive(
- ['BEGIN'],
- ['COMMIT'],
- );
+ $this->expectToSetupPdo(
+ $this->write,
+ ['BEGIN'],
+ ['COMMIT'],
+ );
$this->connection->begin();
$this->connection->commit();
@@ -38,15 +45,15 @@ public function testWhenBeginThenCommitGetsCalledThenRunBeginAndCommitStatements
public function testWhenBeginAndCommitGetsCalledMultipleTimesThenRunStoreAndReleaseSavepoint(): void
{
- $this->write->expects($this->exactly(6))->method('exec')
- ->withConsecutive(
- ['BEGIN'],
- ['SAVEPOINT LEVEL1'],
- ['SAVEPOINT LEVEL2'],
- ['RELEASE SAVEPOINT LEVEL2'],
- ['RELEASE SAVEPOINT LEVEL1'],
- ['COMMIT'],
- );
+ $this->expectToSetupPdo(
+ $this->write,
+ ['BEGIN'],
+ ['SAVEPOINT LEVEL1'],
+ ['SAVEPOINT LEVEL2'],
+ ['RELEASE SAVEPOINT LEVEL2'],
+ ['RELEASE SAVEPOINT LEVEL1'],
+ ['COMMIT'],
+ );
$this->connection->begin();
$this->connection->begin();
@@ -58,11 +65,11 @@ public function testWhenBeginAndCommitGetsCalledMultipleTimesThenRunStoreAndRele
public function testWhenBeginThenRollbackGetsCalledThenRunBeginAndRollbackStatements(): void
{
- $this->write->expects($this->exactly(2))->method('exec')
- ->withConsecutive(
- ['BEGIN'],
- ['ROLLBACK'],
- );
+ $this->expectToSetupPdo(
+ $this->write,
+ ['BEGIN'],
+ ['ROLLBACK'],
+ );
$this->connection->begin();
$this->connection->rollback();
@@ -70,15 +77,15 @@ public function testWhenBeginThenRollbackGetsCalledThenRunBeginAndRollbackStatem
public function testWhenBeginAndRollbackGetsCalledMultipleTimesThenRunStoreAndReleaseSavepoint(): void
{
- $this->write->expects($this->exactly(6))->method('exec')
- ->withConsecutive(
- ['BEGIN'],
- ['SAVEPOINT LEVEL1'],
- ['SAVEPOINT LEVEL2'],
- ['RELEASE SAVEPOINT LEVEL2'],
- ['RELEASE SAVEPOINT LEVEL1'],
- ['ROLLBACK'],
- );
+ $this->expectToSetupPdo(
+ $this->write,
+ ['BEGIN'],
+ ['SAVEPOINT LEVEL1'],
+ ['SAVEPOINT LEVEL2'],
+ ['RELEASE SAVEPOINT LEVEL2'],
+ ['RELEASE SAVEPOINT LEVEL1'],
+ ['ROLLBACK'],
+ );
$this->connection->begin();
$this->connection->begin();
@@ -95,4 +102,17 @@ public function testGivenNoTransactionThenWhenRollbackIsCalledThenThrowAnExcepti
$this->connection->rollback();
}
+
+ /**
+ * @param array ...$params
+ */
+ private function expectToSetupPdo(PDO&MockObject $pdo, array ...$params): void
+ {
+ $matcher = $this->exactly(count($params));
+
+ $pdo
+ ->expects($matcher)
+ ->method('exec')
+ ->with($this->consecutive($matcher, ...$params));
+ }
}
diff --git a/tests/Unit/EntityRecordMapperTest.php b/tests/Unit/EntityRecordMapperTest.php
new file mode 100644
index 0000000..bca33b2
--- /dev/null
+++ b/tests/Unit/EntityRecordMapperTest.php
@@ -0,0 +1,75 @@
+addressRepository = $this->createMock(AddressRepository::class);
+
+ $this->mapper = new UserMapper($this->addressRepository);
+ }
+
+ #[Test] public function get_plain_array_from_first_user(): void
+ {
+ $object = User::first();
+
+ $plain = $this->mapper->plain($object);
+
+ $this->assertSame(User::firstData(), $plain);
+ }
+
+ #[Test] public function get_plain_array_from_second_user(): void
+ {
+ $object = User::second();
+
+ $values = $this->mapper->plain($object);
+
+ $this->assertSame(User::secondData(), $values);
+ }
+
+ #[Test] public function map_first_user(): void
+ {
+ $this->setupLoadAddress(1, Address::first());
+ $data = User::firstData();
+
+ $object = $this->mapper->map($data);
+ initializeLazyObject($object->address);
+
+ $this->assertEquals(User::first(), $object);
+ }
+
+ #[Test] public function map_second_user(): void
+ {
+ $this->setupLoadAddress(2, Address::second());
+ $data = User::secondData();
+
+ $object = $this->mapper->map($data);
+ initializeLazyObject($object->address);
+
+ $this->assertEquals(User::second(), $object);
+ }
+
+ private function setupLoadAddress(int $userId, Address $address): void
+ {
+ $this->addressRepository
+ ->expects($this->once())
+ ->method('loadById')
+ ->with($userId)
+ ->willReturn($address);
+ }
+}
diff --git a/tests/Unit/EntityRecordRepositoryTest.php b/tests/Unit/EntityRecordRepositoryTest.php
new file mode 100644
index 0000000..5204ac4
--- /dev/null
+++ b/tests/Unit/EntityRecordRepositoryTest.php
@@ -0,0 +1,135 @@
+connection = $this->createMock(Connection::class);
+ $this->addressRepository = $this->createMock(AddressRepository::class);
+
+ $this->repository = new UserRepository(
+ $this->connection,
+ new UserMapper($this->addressRepository),
+ );
+ }
+
+ #[Test] public function load_by_id(): void
+ {
+ $this->connection
+ ->expects($this->once())
+ ->method('read')
+ ->with('SELECT * FROM users WHERE id = :id LIMIT 1', ['id' => 'galaxy-1']);
+
+ $this->repository->selectEntityById('galaxy-1');
+ }
+
+ #[Test] public function update_one(): void
+ {
+ $this->connection
+ ->expects($this->exactly(1))
+ ->method('write')
+ ->with(
+ 'UPDATE users SET id = :id, name = :name, date_of_birth = :date_of_birth, address_id = :address_id WHERE id = :id',
+ [
+ 'id' => 1,
+ 'name' => 'First User',
+ 'date_of_birth' => '2020-01-01',
+ 'address_id' => 1,
+ ],
+ );
+
+ $this->repository->updateOne(User::first());
+ }
+
+ #[Test] public function update_many(): void
+ {
+ $matcher = $this->exactly(2);
+
+ $this->connection
+ ->expects($matcher)
+ ->method('write')
+ ->with($this->consecutive(
+ $matcher,
+ [
+ 'UPDATE users SET id = :id, name = :name, date_of_birth = :date_of_birth, address_id = :address_id WHERE id = :id',
+ [
+ 'id' => 1,
+ 'name' => 'First User',
+ 'date_of_birth' => '2020-01-01',
+ 'address_id' => 1,
+ ],
+ ],
+ [
+ 'UPDATE users SET id = :id, name = :name, date_of_birth = :date_of_birth, address_id = :address_id WHERE id = :id',
+ [
+ 'id' => 2,
+ 'name' => 'Second User',
+ 'date_of_birth' => '2022-10-15',
+ 'address_id' => 2,
+ ],
+ ],
+ ));
+
+ $this->repository->updateMany(
+ User::first(),
+ User::second(),
+ );
+ }
+
+ #[Test] public function delete_one(): void
+ {
+ $this->connection
+ ->expects($this->exactly(1))
+ ->method('write')
+ ->with(
+ 'DELETE FROM users WHERE id = :id',
+ ['id' => 1],
+ );
+
+ $this->repository->deleteOne(User::first());
+ }
+
+ #[Test] public function delete_many(): void
+ {
+ $matcher = $this->exactly(2);
+
+ $this->connection
+ ->expects($matcher)
+ ->method('write')
+ ->with($this->consecutive(
+ $matcher,
+ [
+ 'DELETE FROM users WHERE id = :id',
+ ['id' => 1],
+ ],
+ [
+ 'DELETE FROM users WHERE id = :id',
+ ['id' => 2],
+ ],
+ ));
+
+ $this->repository->deleteMany(
+ User::first(),
+ User::second(),
+ );
+ }
+}
diff --git a/tests/Unit/EntityTableDeleteTest.php b/tests/Unit/EntityTableDeleteTest.php
deleted file mode 100644
index ae370f5..0000000
--- a/tests/Unit/EntityTableDeleteTest.php
+++ /dev/null
@@ -1,35 +0,0 @@
-connection = $this->createMock(Connection::class);
- $this->table = new AddressEntityTable($this->connection);
- }
-
- public function testGivenWhereWhenNotEmptyWhenRunQueryWithWhereAndLimitAndReturnOnlyOneEntry(): void
- {
- $address = new Address(id: 'address-xxx', street: "Galaxy Avenue");
-
- $this->connection
- ->expects($this->once())
- ->method('write')
- ->with("DELETE FROM addresses WHERE id = :id", [':id' => 'address-xxx']);
-
- $this->table->delete($address);
- }
-}
diff --git a/tests/Unit/EntityTableLoadByIdTest.php b/tests/Unit/EntityTableLoadByIdTest.php
deleted file mode 100644
index b7f414b..0000000
--- a/tests/Unit/EntityTableLoadByIdTest.php
+++ /dev/null
@@ -1,42 +0,0 @@
-connection = $this->createMock(Connection::class);
- $this->statement = $this->createMock(PDOStatement::class);
- $this->table = new AddressEntityTable($this->connection);
- }
-
- public function testGivenWhereWhenNotEmptyWhenRunQueryWithWhereAndLimitAndReturnOnlyOneEntry(): void
- {
- $this->statement
- ->method('fetch')
- ->willReturn(['id' => 'address-xxx', 'street' => "Galaxy Avenue"]);
- $this->connection
- ->expects($this->once())
- ->method('read')
- ->with("SELECT * FROM addresses WHERE id = :id LIMIT 1", [':id' => 'address-xxx'])
- ->willReturn($this->statement);
-
- $result = $this->table->loadById('address-xxx');
-
- $this->assertEquals(new Address(id: 'address-xxx', street: "Galaxy Avenue"), $result);
- }
-}
diff --git a/tests/Unit/EntityTableUpdateTest.php b/tests/Unit/EntityTableUpdateTest.php
deleted file mode 100644
index 2d6056a..0000000
--- a/tests/Unit/EntityTableUpdateTest.php
+++ /dev/null
@@ -1,38 +0,0 @@
-connection = $this->createMock(Connection::class);
- $this->table = new AddressEntityTable($this->connection);
- }
-
- public function testGivenWhereWhenNotEmptyWhenRunQueryWithWhereAndLimitAndReturnOnlyOneEntry(): void
- {
- $address = new Address(id: 'address-xxx', street: "Galaxy Avenue");
-
- $this->connection
- ->expects($this->once())
- ->method('write')
- ->with(
- "UPDATE addresses SET street = :street, id = :id WHERE id = :id",
- [':street' => 'Galaxy Avenue', ':id' => 'address-xxx'],
- );
-
- $this->table->update($address);
- }
-}
diff --git a/tests/Unit/RecordMapperTest.php b/tests/Unit/RecordMapperTest.php
new file mode 100644
index 0000000..16fa64a
--- /dev/null
+++ b/tests/Unit/RecordMapperTest.php
@@ -0,0 +1,56 @@
+mapper = new AddressMapper();
+ }
+
+ #[Test] public function get_plain_array_from_first_address(): void
+ {
+ $object = Address::first();
+
+ $plain = $this->mapper->plain($object);
+
+ $this->assertSame(Address::firstRowData(), $plain);
+ }
+
+ #[Test] public function get_plain_array_from_second_address(): void
+ {
+ $object = Address::second();
+
+ $plain = $this->mapper->plain($object);
+
+ $this->assertSame(Address::secondRowData(), $plain);
+ }
+
+ #[Test] public function map_first_address(): void
+ {
+ $data = Address::firstRowData();
+
+ $object = $this->mapper->map($data);
+
+ $this->assertEquals(Address::first(), $object);
+ }
+
+ #[Test] public function map_second_address(): void
+ {
+ $data = Address::secondRowData();
+
+ $object = $this->mapper->map($data);
+
+ $this->assertEquals(Address::second(), $object);
+ }
+}
diff --git a/tests/Unit/RecordRepositoryTest.php b/tests/Unit/RecordRepositoryTest.php
new file mode 100644
index 0000000..7ca35b9
--- /dev/null
+++ b/tests/Unit/RecordRepositoryTest.php
@@ -0,0 +1,236 @@
+connection = $this->createMock(Connection::class);
+ $this->statement = $this->createMock(PDOStatement::class);
+
+ $this->manager = new class (new AddressMapper(), $this->connection, 'addresses') extends RecordRepository
+ {
+ };
+ }
+
+ #[Test] public function insert(): void
+ {
+ $address = Address::first();
+
+ $this->connection
+ ->expects($this->once())
+ ->method('write')
+ ->with(
+ "INSERT INTO addresses (id, street, number, floor, active, type, created_at, deleted_at) VALUES (:id, :street, :number, :floor, :active, :type, :created_at, :deleted_at)",
+ [
+ 'id' => 1,
+ 'street' => 'First Avenue',
+ 'number' => 145.45,
+ 'floor' => 1,
+ 'active' => true,
+ 'type' => 'RESIDENCE',
+ 'created_at' => '2025-05-01T10:15:20+00:00',
+ 'deleted_at' => '2025-05-10T11:16:30+00:00',
+ ],
+ );
+
+ $this->manager->insertOne($address);
+ }
+
+ #[Test] public function load_by(): void
+ {
+ $this->statement
+ ->method('fetch')
+ ->willReturn(Address::secondRowData());
+ $this->connection
+ ->expects($this->once())
+ ->method('read')
+ ->with(
+ "SELECT * FROM addresses WHERE id = :id LIMIT 1",
+ ['id' => 'address-xxx'],
+ )
+ ->willReturn($this->statement);
+
+ $result = $this->manager->selectOneWhere(['id' => 'address-xxx']);
+
+ $this->assertEquals(Address::second(), $result);
+ }
+
+ #[Test] public function load_by_query(): void
+ {
+ $this->statement
+ ->method('fetch')
+ ->willReturn(Address::firstRowData());
+ $this->connection
+ ->expects($this->once())
+ ->method('read')
+ ->with("select * from addresses where id LIKE :id", [':id' => 'address-xxx'])
+ ->willReturn($this->statement);
+
+ $result = $this->manager->selectOneByQuery("select * from addresses where id LIKE :id", [':id' => 'address-xxx']);
+
+ $this->assertEquals(Address::first(), $result);
+ }
+
+ #[Test] public function list_by(): void
+ {
+ $this->statement
+ ->method('fetch')
+ ->willReturnOnConsecutiveCalls(
+ Address::firstRowData(),
+ Address::secondRowData(),
+ null,
+ );
+
+ $this->connection
+ ->expects($this->once())
+ ->method('read')
+ ->with(
+ 'SELECT * FROM addresses WHERE id = :id AND street = :street LIMIT 5 OFFSET 15',
+ ['id' => 'address-xxx', 'street' => "Galaxy Avenue"],
+ )
+ ->willReturn($this->statement);
+
+ $result = $this->manager->selectManyWhere(
+ ['id' => 'address-xxx', 'street' => 'Galaxy Avenue'],
+ limit: 5,
+ offset: 15,
+ );
+
+ $this->assertEquals(
+ [
+ Address::first(),
+ Address::second(),
+ ],
+ iterator_to_array($result),
+ );
+ }
+
+ public function list_by_returns_multiple_entries(): void
+ {
+ $this->statement
+ ->method('fetch')
+ ->willReturnOnConsecutiveCalls(
+ Address::firstRowData(),
+ Address::secondRowData(),
+ null,
+ );
+
+ $this->connection
+ ->expects($this->once())
+ ->method('read')
+ ->with("SELECT * FROM addresses", [])
+ ->willReturn($this->statement);
+
+ $result = $this->manager->selectManyWhere();
+
+ $this->assertEquals(
+ [
+ Address::first(),
+ Address::second(),
+ ],
+ iterator_to_array($result),
+ );
+ }
+
+ #[Test] public function list_by_query(): void
+ {
+ $this->statement
+ ->method('fetch')
+ ->willReturnOnConsecutiveCalls(
+ Address::firstRowData(),
+ Address::secondRowData(),
+ null,
+ );
+
+ $this->connection
+ ->expects($this->once())
+ ->method('read')
+ ->with("SELECT * FROM addresses WHERE foo = :foo", ['foo' => 'bar'])
+ ->willReturn($this->statement);
+
+ $result = $this->manager->selectManyByQuery('SELECT * FROM addresses WHERE foo = :foo', ['foo' => 'bar']);
+
+ $this->assertEquals(
+ [
+ Address::first(),
+ Address::second(),
+ ],
+ iterator_to_array($result),
+ );
+ }
+
+ #[Test] public function exists_returns_true(): void
+ {
+ $this->statement
+ ->method('fetch')
+ ->willReturn(Address::firstRowData());
+ $this->connection
+ ->expects($this->once())
+ ->method('read')
+ ->with("SELECT * FROM addresses WHERE id = :id LIMIT 1", ['id' => 'address-xxx'])
+ ->willReturn($this->statement);
+
+ $exists = $this->manager->existsWhere(['id' => 'address-xxx']);
+
+ $this->assertTrue($exists);
+ }
+
+ #[Test] public function exists_returns_false(): void
+ {
+ $this->statement
+ ->method('fetch')
+ ->willReturn(null);
+ $this->connection
+ ->expects($this->once())
+ ->method('read')
+ ->with("SELECT * FROM addresses WHERE id = :id LIMIT 1", ['id' => 'address-xxx'])
+ ->willReturn($this->statement);
+
+ $exists = $this->manager->existsWhere(['id' => 'address-xxx']);
+
+ $this->assertFalse($exists);
+ }
+
+ #[Test] public function delete_where(): void
+ {
+ $this->connection
+ ->expects($this->once())
+ ->method('write')
+ ->with(
+ "DELETE FROM addresses WHERE id = :id",
+ ['id' => 'address-xxx'],
+ );
+
+ $this->manager->deleteWhere(['id' => 'address-xxx']);
+ }
+
+ #[Test] public function update(): void
+ {
+ $this->connection
+ ->expects($this->once())
+ ->method('write')
+ ->with(
+ "UPDATE addresses SET street = :street WHERE id = :id",
+ ['street' => 'Galaxy Avenue', 'id' => 'address-xxx'],
+ );
+
+ $this->manager->updateWhere(['street' => 'Galaxy Avenue'], ['id' => 'address-xxx']);
+ }
+}
diff --git a/tests/Unit/TableDeleteWhereTest.php b/tests/Unit/TableDeleteWhereTest.php
deleted file mode 100644
index b95aa50..0000000
--- a/tests/Unit/TableDeleteWhereTest.php
+++ /dev/null
@@ -1,35 +0,0 @@
-connection = $this->createMock(Connection::class);
- $this->table = new AddressTable($this->connection);
- }
-
- public function testGivenWhereWhenNotEmptyWhenRunQueryWithWhereAndLimitAndReturnOnlyOneEntry(): void
- {
- $this->connection
- ->expects($this->once())
- ->method('write')
- ->with(
- "DELETE FROM addresses WHERE id = :id",
- [':id' => 'address-xxx'],
- );
-
- $this->table->deleteWhere(['id' => 'address-xxx']);
- }
-}
diff --git a/tests/Unit/TableExistsTest.php b/tests/Unit/TableExistsTest.php
deleted file mode 100644
index 1a4151d..0000000
--- a/tests/Unit/TableExistsTest.php
+++ /dev/null
@@ -1,57 +0,0 @@
-connection = $this->createMock(Connection::class);
- $this->statement = $this->createMock(PDOStatement::class);
- $this->table = new AddressTable($this->connection);
- }
-
- public function testGivenTheConditionsWhenSelectReturnsAnEntryThenExistIsTrue(): void
- {
- $this->statement
- ->method('fetch')
- ->willReturn(['id' => 'address-xxx', 'street' => "Galaxy Avenue"]);
- $this->connection
- ->expects($this->once())
- ->method('read')
- ->with("SELECT * FROM addresses WHERE id = :id LIMIT 1", [':id' => 'address-xxx'])
- ->willReturn($this->statement);
-
- $exists = $this->table->exists(['id' => 'address-xxx']);
-
- $this->assertTrue($exists);
- }
-
- public function testGivenTheConditionsWhenSelectReturnsNullThenExistIsFalse(): void
- {
- $this->statement
- ->method('fetch')
- ->willReturn(null);
- $this->connection
- ->expects($this->once())
- ->method('read')
- ->with("SELECT * FROM addresses WHERE id = :id LIMIT 1", [':id' => 'address-xxx'])
- ->willReturn($this->statement);
-
- $exists = $this->table->exists(['id' => 'address-xxx']);
-
- $this->assertFalse($exists);
- }
-}
diff --git a/tests/Unit/TableInsertTest.php b/tests/Unit/TableInsertTest.php
deleted file mode 100644
index 0652e1c..0000000
--- a/tests/Unit/TableInsertTest.php
+++ /dev/null
@@ -1,38 +0,0 @@
-connection = $this->createMock(Connection::class);
- $this->table = new AddressTable($this->connection);
- }
-
- public function testGivenAnEntryThenRunInsertWithItsData(): void
- {
- $address = new Address("address-xxx", "Galaxy Avenue");
-
- $this->connection
- ->expects($this->once())
- ->method('write')
- ->with(
- "INSERT INTO addresses (id, street) VALUES (:id, :street)",
- ['id' => 'address-xxx', 'street' => "Galaxy Avenue"],
- );
-
- $this->table->insert($address);
- }
-}
diff --git a/tests/Unit/TableLoadByQueryTest.php b/tests/Unit/TableLoadByQueryTest.php
deleted file mode 100644
index e1a3142..0000000
--- a/tests/Unit/TableLoadByQueryTest.php
+++ /dev/null
@@ -1,42 +0,0 @@
-connection = $this->createMock(Connection::class);
- $this->statement = $this->createMock(PDOStatement::class);
- $this->table = new AddressTable($this->connection);
- }
-
- public function testGivenASqlQueryAndItsBindingsThenBypassTheQueryToTheConnectionAndReturnTheFirstItem(): void
- {
- $this->statement
- ->method('fetch')
- ->willReturn(['id' => 'address-xxx', 'street' => "Galaxy Avenue"]);
- $this->connection
- ->expects($this->once())
- ->method('read')
- ->with("select * from addresses where id LIKE :id", [':id' => 'address-xxx'])
- ->willReturn($this->statement);
-
- $result = $this->table->loadByQuery("select * from addresses where id LIKE :id", [':id' => 'address-xxx']);
-
- $this->assertEquals(new Address(id: 'address-xxx', street: "Galaxy Avenue"), $result);
- }
-}
diff --git a/tests/Unit/TableLoadByTest.php b/tests/Unit/TableLoadByTest.php
deleted file mode 100644
index d3f75d4..0000000
--- a/tests/Unit/TableLoadByTest.php
+++ /dev/null
@@ -1,45 +0,0 @@
-connection = $this->createMock(Connection::class);
- $this->statement = $this->createMock(PDOStatement::class);
- $this->table = new AddressTable($this->connection);
- }
-
- public function testGivenWhereWhenNotEmptyWhenRunQueryWithWhereAndLimitAndReturnOnlyOneEntry(): void
- {
- $this->statement
- ->method('fetch')
- ->willReturn(['id' => 'address-xxx', 'street' => "Galaxy Avenue"]);
- $this->connection
- ->expects($this->once())
- ->method('read')
- ->with(
- "SELECT * FROM addresses WHERE id = :id LIMIT 1",
- [':id' => 'address-xxx'],
- )
- ->willReturn($this->statement);
-
- $result = $this->table->loadBy(['id' => 'address-xxx']);
-
- $this->assertEquals(new Address(id: 'address-xxx', street: "Galaxy Avenue"), $result);
- }
-}
diff --git a/tests/Unit/TableSelectByQueryTest.php b/tests/Unit/TableSelectByQueryTest.php
deleted file mode 100644
index 699ebee..0000000
--- a/tests/Unit/TableSelectByQueryTest.php
+++ /dev/null
@@ -1,56 +0,0 @@
-connection = $this->createMock(Connection::class);
- $this->statement = $this->createMock(PDOStatement::class);
- $this->table = new AddressTable($this->connection);
- }
-
- public function testGivenASqlQueryAndItsBindingsThenBypassTheQueryToTheConnectionAndReturnTheItemList(): void
- {
- $this->statement
- ->method('fetch')
- ->willReturnOnConsecutiveCalls(
- ['id' => 'address-xxx', 'street' => "Galaxy Avenue"],
- ['id' => 'address-yyy', 'street' => "Galaxy Highway"],
- null,
- );
-
- $this->connection
- ->expects($this->once())
- ->method('read')
- ->with("select * from addresses where street LIKE :street", [':street' => 'Galaxy%'])
- ->willReturn($this->statement);
-
- $result = $this->table->findByQuery(
- "select * from addresses where street LIKE :street",
- [':street' => 'Galaxy%'],
- );
-
- $this->assertEquals(
- [
- new Address(id: 'address-xxx', street: "Galaxy Avenue"),
- new Address(id: 'address-yyy', street: "Galaxy Highway"),
- ],
- iterator_to_array($result),
- );
- }
-}
diff --git a/tests/Unit/TableSelectTest.php b/tests/Unit/TableSelectTest.php
deleted file mode 100644
index c1acae2..0000000
--- a/tests/Unit/TableSelectTest.php
+++ /dev/null
@@ -1,105 +0,0 @@
-connection = $this->createMock(Connection::class);
- $this->statement = $this->createMock(PDOStatement::class);
- $this->table = new AddressTable($this->connection);
- }
-
- public function testGivenWhereConditionWhenNotEmptyThenSelectWithWhereStatement(): void
- {
- $this->statement
- ->method('fetch')
- ->willReturnOnConsecutiveCalls(['id' => 'address-xxx', 'street' => "Galaxy Avenue"], null);
-
- $this->connection
- ->expects($this->once())
- ->method('read')
- ->with(
- "SELECT * FROM addresses WHERE id = :id AND street = :street",
- [':id' => 'address-xxx', ':street' => "Galaxy Avenue"],
- )
- ->willReturn($this->statement);
-
- $result = $this->table->findBy(['id' => 'address-xxx', 'street' => 'Galaxy Avenue']);
-
- $this->assertEquals(
- [
- new Address(id: 'address-xxx', street: "Galaxy Avenue"),
- ],
- iterator_to_array($result),
- );
- }
-
- public function testGivenWhereConditionWhenEmptyThenSelectWithoutWhereStatement(): void
- {
- $this->statement
- ->method('fetch')
- ->willReturnOnConsecutiveCalls(
- ['id' => 'address-xxx', 'street' => "Galaxy Avenue"],
- ['id' => 'address-yyy', 'street' => "Galaxy Highway"],
- null,
- );
-
- $this->connection
- ->expects($this->once())
- ->method('read')
- ->with("SELECT * FROM addresses", [])
- ->willReturn($this->statement);
-
- $result = $this->table->findBy([]);
-
- $this->assertEquals(
- [
- new Address(id: 'address-xxx', street: "Galaxy Avenue"),
- new Address(id: 'address-yyy', street: "Galaxy Highway"),
- ],
- iterator_to_array($result),
- );
- }
-
- public function testGivenTheLimitAndOffsetThenSelectWithLimitOffsetStatement(): void
- {
- $this->statement
- ->method('fetch')
- ->willReturnOnConsecutiveCalls(
- ['id' => 'address-xxx', 'street' => "Galaxy Avenue"],
- ['id' => 'address-yyy', 'street' => "Galaxy Highway"],
- null,
- );
-
- $this->connection
- ->expects($this->once())
- ->method('read')
- ->with("SELECT * FROM addresses LIMIT 5 OFFSET 15", [])
- ->willReturn($this->statement);
-
- $result = $this->table->findBy(where: [], limit: 5, offset: 15);
-
- $this->assertEquals(
- [
- new Address(id: 'address-xxx', street: "Galaxy Avenue"),
- new Address(id: 'address-yyy', street: "Galaxy Highway"),
- ],
- iterator_to_array($result),
- );
- }
-}
diff --git a/tests/Unit/TableTest.php b/tests/Unit/TableTest.php
deleted file mode 100644
index e8ddb80..0000000
--- a/tests/Unit/TableTest.php
+++ /dev/null
@@ -1,32 +0,0 @@
-createMock(Connection::class);
-
- $this->table = new AddressTable($connection);
- }
-
- public function testGetEntryValues(): void
- {
- $address = new Address(id: 'address-xxx', street: 'Galaxy Avenue');
-
- $values = $this->table->valuesOf($address);
-
- $this->assertEquals(['id' => 'address-xxx', 'street' => 'Galaxy Avenue'], $values);
- }
-}
diff --git a/tests/Unit/TableUpdateWhereTest.php b/tests/Unit/TableUpdateWhereTest.php
deleted file mode 100644
index 6ed02bc..0000000
--- a/tests/Unit/TableUpdateWhereTest.php
+++ /dev/null
@@ -1,35 +0,0 @@
-connection = $this->createMock(Connection::class);
- $this->table = new AddressTable($this->connection);
- }
-
- public function testGivenWhereWhenNotEmptyWhenRunQueryWithWhereAndLimitAndReturnOnlyOneEntry(): void
- {
- $this->connection
- ->expects($this->once())
- ->method('write')
- ->with(
- "UPDATE addresses SET street = :street WHERE id = :id",
- [':street' => 'Galaxy Avenue', ':id' => 'address-xxx'],
- );
-
- $this->table->updateWhere(['street' => 'Galaxy Avenue'], ['id' => 'address-xxx']);
- }
-}