diff --git a/.editorconfig b/.editorconfig
index 3aaad72..fe20895 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -10,6 +10,9 @@ trim_trailing_whitespace = true
[*.json]
indent_size = 2
+[*.md]
+indent_size = 2
+
[*.neon]
indent_style = tab
diff --git a/.gitattributes b/.gitattributes
index ec9d3ba..391a438 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -8,6 +8,8 @@
/.yamllint.yaml export-ignore
/composer-require-checker.json export-ignore
/composer.lock export-ignore
+/infection.json export-ignore
/Makefile export-ignore
/psalm-baseline.xml export-ignore
/psalm.xml export-ignore
+/rector.php export-ignore
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 01c2491..1d76505 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1 +1,3 @@
+# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners#codeowners-file-size
+
* @ergebnis-bot @localheinz
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index efb1a13..2455c52 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -47,6 +47,30 @@ make dependency-analysis
to run a dependency analysis.
+## Refactoring
+
+We are using [`rector/rector`](https://github.com/rectorphp/rector) to automatically refactor code.
+
+Run
+
+```sh
+make refactoring
+```
+
+to automatically refactor code.
+
+## Security Analysis
+
+We are using [`composer`](https://github.com/composer/composer) to run a security analysis.
+
+Run
+
+```sh
+make security-analysis
+```
+
+to run a security analysis.
+
## Static Code Analysis
We are using [`vimeo/psalm`](https://github.com/vimeo/psalm) to statically analyze the code.
@@ -83,6 +107,18 @@ make tests
to run all the tests.
+## Mutation Tests
+
+We are using [`infection/infection`](https://github.com/infection/infection) to ensure a minimum quality of the tests.
+
+Enable `Xdebug` and run
+
+```sh
+make mutation-tests
+```
+
+to run mutation tests.
+
## Extra lazy?
Run
diff --git a/.github/settings.yml b/.github/settings.yml
index e4361f3..1a35f62 100644
--- a/.github/settings.yml
+++ b/.github/settings.yml
@@ -13,20 +13,23 @@ branches:
require_code_owner_reviews: true
required_approving_review_count: 1
required_status_checks:
- contexts:
- - "Code Coverage (8.0, locked)"
- - "Coding Standards (8.0, locked)"
- - "Dependency Analysis (8.0, locked)"
- - "Static Code Analysis (8.0, locked)"
- - "Tests (8.0, highest)"
- - "Tests (8.0, locked)"
- - "Tests (8.0, lowest)"
- - "Tests (8.1, highest)"
- - "Tests (8.1, locked)"
- - "Tests (8.1, lowest)"
- - "Tests (8.2, highest)"
- - "Tests (8.2, locked)"
- - "Tests (8.2, lowest)"
+ checks:
+ - context: "Code Coverage (8.0, locked)"
+ - context: "Coding Standards (8.0, locked)"
+ - context: "Dependency Analysis (8.0, locked)"
+ - context: "Mutation Tests (8.0, locked)"
+ - context: "Refactoring (8.0, locked)"
+ - context: "Security Analysis (8.0, locked)"
+ - context: "Static Code Analysis (8.0, locked)"
+ - context: "Tests (8.0, highest)"
+ - context: "Tests (8.0, locked)"
+ - context: "Tests (8.0, lowest)"
+ - context: "Tests (8.1, highest)"
+ - context: "Tests (8.1, locked)"
+ - context: "Tests (8.1, lowest)"
+ - context: "Tests (8.2, highest)"
+ - context: "Tests (8.2, locked)"
+ - context: "Tests (8.2, lowest)"
strict: false
restrictions:
diff --git a/.github/workflows/integrate.yaml b/.github/workflows/integrate.yaml
index 85f0c53..94c0582 100644
--- a/.github/workflows/integrate.yaml
+++ b/.github/workflows/integrate.yaml
@@ -59,10 +59,11 @@ jobs:
XDEBUG_MODE: "coverage"
run: "vendor/bin/phpunit --colors=always --configuration=test/Unit/phpunit.xml --coverage-clover=.build/phpunit/logs/clover.xml"
- - name: "Send code coverage report to Codecov.io"
- env:
- CODECOV_TOKEN: "${{ secrets.CODECOV_TOKEN }}"
- run: "bash <(curl -s https://codecov.io/bash)"
+ - name: "Send code coverage report to codecov.io"
+ uses: "codecov/codecov-action@v3.1.1"
+ with:
+ files: ".build/phpunit/logs/clover.xml"
+ token: "${{ secrets.CODECOV_TOKEN }}"
coding-standards:
name: "Coding Standards"
@@ -82,7 +83,7 @@ jobs:
uses: "actions/checkout@v3.2.0"
- name: "Lint YAML files"
- uses: "ibiqlik/action-yamllint@v3.1"
+ uses: "ibiqlik/action-yamllint@v3.1.1"
with:
config_file: ".yamllint.yaml"
file_or_dir: "."
@@ -132,7 +133,7 @@ jobs:
php-${{ matrix.php-version }}-php-cs-fixer-
- name: "Run friendsofphp/php-cs-fixer"
- run: "vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --diff --dry-run --verbose"
+ run: "vendor/bin/php-cs-fixer fix --ansi --config=.php-cs-fixer.php --diff --dry-run --verbose"
dependency-analysis:
name: "Dependency Analysis"
@@ -179,6 +180,143 @@ jobs:
- name: "Run maglnet/composer-require-checker"
run: ".phive/composer-require-checker check --config-file=$(pwd)/composer-require-checker.json"
+ mutation-tests:
+ name: "Mutation Tests"
+
+ runs-on: "ubuntu-latest"
+
+ strategy:
+ matrix:
+ php-version:
+ - "8.0"
+
+ dependencies:
+ - "locked"
+
+ steps:
+ - name: "Checkout"
+ uses: "actions/checkout@v3.2.0"
+
+ - name: "Set up PHP"
+ uses: "shivammathur/setup-php@2.23.0"
+ with:
+ coverage: "xdebug"
+ extensions: "none, ctype, dom, json, mbstring, phar, simplexml, tokenizer, xml, xmlwriter"
+ php-version: "${{ matrix.php-version }}"
+
+ - name: "Set up problem matchers for PHP"
+ run: "echo \"::add-matcher::${{ runner.tool_cache }}/php.json\""
+
+ - name: "Determine composer cache directory"
+ uses: "ergebnis/.github/actions/composer/determine-cache-directory@1.7.0"
+
+ - name: "Cache dependencies installed with composer"
+ uses: "actions/cache@v3.2.2"
+ with:
+ path: "${{ env.COMPOSER_CACHE_DIR }}"
+ key: "php-${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-${{ hashFiles('composer.lock') }}"
+ restore-keys: "php-${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-"
+
+ - name: "Install ${{ matrix.dependencies }} dependencies with composer"
+ uses: "ergebnis/.github/actions/composer/install@1.7.0"
+ with:
+ dependencies: "${{ matrix.dependencies }}"
+
+ - name: "Run mutation tests with Xdebug and infection/infection"
+ env:
+ XDEBUG_MODE: "coverage"
+ run: "vendor/bin/infection --ansi --configuration=infection.json --logger-github"
+
+ refactoring:
+ name: "Refactoring"
+
+ runs-on: "ubuntu-latest"
+
+ strategy:
+ matrix:
+ php-version:
+ - "8.0"
+
+ dependencies:
+ - "locked"
+
+ steps:
+ - name: "Checkout"
+ uses: "actions/checkout@v3.2.0"
+
+ - name: "Set up PHP"
+ uses: "shivammathur/setup-php@2.23.0"
+ with:
+ coverage: "none"
+ extensions: "none, ctype, dom, intl, json, mbstring, phar, simplexml, tokenizer, xml, xmlwriter"
+ php-version: "${{ matrix.php-version }}"
+
+ - name: "Set up problem matchers for PHP"
+ run: "echo \"::add-matcher::${{ runner.tool_cache }}/php.json\""
+
+ - name: "Determine composer cache directory"
+ uses: "ergebnis/.github/actions/composer/determine-cache-directory@1.7.0"
+
+ - name: "Cache dependencies installed with composer"
+ uses: "actions/cache@v3.2.2"
+ with:
+ path: "${{ env.COMPOSER_CACHE_DIR }}"
+ key: "php-${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-${{ hashFiles('composer.lock') }}"
+ restore-keys: "php-${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-"
+
+ - name: "Install ${{ matrix.dependencies }} dependencies with composer"
+ uses: "ergebnis/.github/actions/composer/install@1.7.0"
+ with:
+ dependencies: "${{ matrix.dependencies }}"
+
+ - name: "Create cache directory for rector/rector"
+ run: "mkdir -p .build/rector"
+
+ - name: "Cache cache directory for rector/rector"
+ uses: "actions/cache@v3.2.2"
+ with:
+ path: ".build/rector"
+ key: "php-${{ matrix.php-version }}-rector-${{ github.ref_name }}"
+ restore-keys: |
+ php-${{ matrix.php-version }}-rector-main
+ php-${{ matrix.php-version }}-rector-
+
+ - name: "Run automated refactoring with rector/rector"
+ run: "vendor/bin/rector --ansi --config=rector.php --dry-run"
+
+ security-analysis:
+ name: "Security Analysis"
+
+ runs-on: "ubuntu-latest"
+
+ strategy:
+ matrix:
+ php-version:
+ - "8.0"
+
+ dependencies:
+ - "locked"
+
+ steps:
+ - name: "Checkout"
+ uses: "actions/checkout@v3.2.0"
+
+ - name: "Set up PHP"
+ uses: "shivammathur/setup-php@2.23.0"
+ with:
+ coverage: "none"
+ extensions: "none, ctype, dom, json, mbstring, phar, simplexml, tokenizer, xml, xmlwriter"
+ php-version: "${{ matrix.php-version }}"
+
+ - name: "Set up problem matchers for PHP"
+ run: "echo \"::add-matcher::${{ runner.tool_cache }}/php.json\""
+
+ - name: "Validate composer.json and composer.lock"
+ run: "composer validate --ansi --strict"
+
+ - name: "Check installed packages for security vulnerability advisories"
+ run: "composer audit --ansi"
+
static-code-analysis:
name: "Static Code Analysis"
diff --git a/.github/workflows/merge.yaml b/.github/workflows/merge.yaml
index 0734507..63c5227 100644
--- a/.github/workflows/merge.yaml
+++ b/.github/workflows/merge.yaml
@@ -33,8 +33,8 @@ jobs:
- name: "Assign @ergebnis-bot"
uses: "ergebnis/.github/actions/github/pull-request/add-assignee@1.7.0"
with:
- github-token: "${{ secrets.ERGEBNIS_BOT_TOKEN }}"
assignee: "ergebnis-bot"
+ github-token: "${{ secrets.ERGEBNIS_BOT_TOKEN }}"
- name: "Approve pull request"
uses: "ergebnis/.github/actions/github/pull-request/approve@1.7.0"
diff --git a/.github/workflows/renew.yaml b/.github/workflows/renew.yaml
index 6f329f4..c8770d4 100644
--- a/.github/workflows/renew.yaml
+++ b/.github/workflows/renew.yaml
@@ -67,7 +67,7 @@ jobs:
php-${{ matrix.php-version }}-php-cs-fixer-
- name: "Run friendsofphp/php-cs-fixer"
- run: "vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --diff --verbose"
+ run: "vendor/bin/php-cs-fixer fix --ansi --config=.php-cs-fixer.php --diff --verbose"
- name: "Commit modified files"
uses: "stefanzweifel/git-auto-commit-action@v4.16.0"
diff --git a/.phive/composer-require-checker b/.phive/composer-require-checker
index e8c4cee..a190508 100755
Binary files a/.phive/composer-require-checker and b/.phive/composer-require-checker differ
diff --git a/.phive/phars.xml b/.phive/phars.xml
index 366a8bf..2d3fdb2 100644
--- a/.phive/phars.xml
+++ b/.phive/phars.xml
@@ -1,4 +1,4 @@
-
+
diff --git a/Makefile b/Makefile
index 2364722..1e56f0b 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
.PHONY: it
-it: coding-standards static-code-analysis tests ## Runs the coding-standards, static-code-analysis, and tests targets
+it: refactoring coding-standards security-analysis static-code-analysis tests ## Runs the refactoring, coding-standards, security-analysis, static-code-analysis, and tests targets
.PHONY: code-coverage
code-coverage: vendor ## Collects coverage from running unit tests with phpunit/phpunit
@@ -7,9 +7,9 @@ code-coverage: vendor ## Collects coverage from running unit tests with phpunit/
vendor/bin/phpunit --configuration=test/Unit/phpunit.xml --coverage-text
.PHONY: coding-standards
-coding-standards: vendor ## Normalizes composer.json with ergebnis/composer-normalize, lints YAML files with yamllint and fixes code style issues with friendsofphp/php-cs-fixer
- composer normalize
+coding-standards: vendor ## Lints YAML files with yamllint, normalizes composer.json with ergebnis/composer-normalize, and fixes code style issues with friendsofphp/php-cs-fixer
yamllint -c .yamllint.yaml --strict .
+ composer normalize
mkdir -p .build/php-cs-fixer
vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --diff --verbose
@@ -21,11 +21,24 @@ dependency-analysis: vendor ## Runs a dependency analysis with maglnet/composer-
help: ## Displays this list of targets with descriptions
@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[32m%-30s\033[0m %s\n", $$1, $$2}'
+.PHONY: mutation-tests
+mutation-tests: vendor ## Runs mutation tests with infection/infection
+ mkdir -p .build/infection
+ vendor/bin/infection --configuration=infection.json
+
+.PHONY: refactoring
+refactoring: vendor ## Runs automated refactoring with rector/rector
+ vendor/bin/rector process --config=rector.php
+
+.PHONY: security-analysis
+security-analysis: vendor ## Runs a security analysis with composer
+ composer audit
+
.PHONY: static-code-analysis
static-code-analysis: vendor ## Runs a static code analysis with vimeo/psalm
mkdir -p .build/psalm
vendor/bin/psalm --config=psalm.xml --clear-cache
- vendor/bin/psalm --config=psalm.xml --diff --show-info=false --stats --threads=4
+ vendor/bin/psalm --config=psalm.xml --show-info=false --stats --threads=4
.PHONY: static-code-analysis-baseline
static-code-analysis-baseline: vendor ## Generates a baseline for static code analysis with vimeo/psalm
diff --git a/README.md b/README.md
index f8c5a2e..5dcfcac 100644
--- a/README.md
+++ b/README.md
@@ -138,6 +138,6 @@ This package is licensed using the MIT License.
Please have a look at [`LICENSE.md`](LICENSE.md).
-## Curious what I am building?
+## Curious what I am up to?
-:mailbox_with_mail: [Subscribe to my list](https://localheinz.com/projects/), and I will occasionally send you an email to let you know what I am working on.
+Follow me on [Twitter](https://twitter.com/localheinz)!
diff --git a/composer.json b/composer.json
index a4a7108..b0f0eb8 100644
--- a/composer.json
+++ b/composer.json
@@ -26,8 +26,10 @@
"ergebnis/composer-normalize": "^2.29.0",
"ergebnis/license": "^2.1.0",
"ergebnis/php-cs-fixer-config": "^5.0.1",
+ "infection/infection": "~0.26.6",
"phpunit/phpunit": "^9.5.27",
"psalm/plugin-phpunit": "~0.18.4",
+ "rector/rector": "~0.15.2",
"vimeo/psalm": "^5.4.0"
},
"autoload": {
@@ -42,7 +44,8 @@
},
"config": {
"allow-plugins": {
- "ergebnis/composer-normalize": true
+ "ergebnis/composer-normalize": true,
+ "infection/extension-installer": true
},
"platform": {
"php": "8.0.25"
diff --git a/composer.lock b/composer.lock
index e89b143..c35632d 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "b2de899208991c9092dd14fc78a14cbe",
+ "content-hash": "5d7248f5f2006a7630a7ad0e9f32326c",
"packages": [
{
"name": "fakerphp/faker",
@@ -362,6 +362,97 @@
],
"time": "2021-03-30T17:13:30+00:00"
},
+ {
+ "name": "colinodell/json5",
+ "version": "v2.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/colinodell/json5.git",
+ "reference": "15b063f8cb5e6deb15f0cd39123264ec0d19c710"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/colinodell/json5/zipball/15b063f8cb5e6deb15f0cd39123264ec0d19c710",
+ "reference": "15b063f8cb5e6deb15f0cd39123264ec0d19c710",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "ext-mbstring": "*",
+ "php": "^7.1.3|^8.0"
+ },
+ "conflict": {
+ "scrutinizer/ocular": "1.7.*"
+ },
+ "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"
+ },
+ "bin": [
+ "bin/json5"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.0-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/global.php"
+ ],
+ "psr-4": {
+ "ColinODell\\Json5\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Colin O'Dell",
+ "email": "colinodell@gmail.com",
+ "homepage": "https://www.colinodell.com",
+ "role": "Developer"
+ }
+ ],
+ "description": "UTF-8 compatible JSON5 parser for PHP",
+ "homepage": "https://github.com/colinodell/json5",
+ "keywords": [
+ "JSON5",
+ "json",
+ "json5_decode",
+ "json_decode"
+ ],
+ "support": {
+ "issues": "https://github.com/colinodell/json5/issues",
+ "source": "https://github.com/colinodell/json5/tree/v2.3.0"
+ },
+ "funding": [
+ {
+ "url": "https://www.colinodell.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.paypal.me/colinpodell/10.00",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/colinodell",
+ "type": "github"
+ },
+ {
+ "url": "https://www.patreon.com/colinodell",
+ "type": "patreon"
+ }
+ ],
+ "time": "2022-12-27T16:44:40+00:00"
+ },
{
"name": "composer/package-versions-deprecated",
"version": "1.11.99.5",
@@ -1584,6 +1675,309 @@
],
"time": "2022-12-18T00:47:22+00:00"
},
+ {
+ "name": "infection/abstract-testframework-adapter",
+ "version": "0.5.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/infection/abstract-testframework-adapter.git",
+ "reference": "18925e20d15d1a5995bb85c9dc09e8751e1e069b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/infection/abstract-testframework-adapter/zipball/18925e20d15d1a5995bb85c9dc09e8751e1e069b",
+ "reference": "18925e20d15d1a5995bb85c9dc09e8751e1e069b",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.4 || ^8.0"
+ },
+ "require-dev": {
+ "ergebnis/composer-normalize": "^2.8",
+ "friendsofphp/php-cs-fixer": "^2.17",
+ "phpunit/phpunit": "^9.5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Infection\\AbstractTestFramework\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Maks Rafalko",
+ "email": "maks.rafalko@gmail.com"
+ }
+ ],
+ "description": "Abstract Test Framework Adapter for Infection",
+ "support": {
+ "issues": "https://github.com/infection/abstract-testframework-adapter/issues",
+ "source": "https://github.com/infection/abstract-testframework-adapter/tree/0.5.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/infection",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/infection",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2021-08-17T18:49:12+00:00"
+ },
+ {
+ "name": "infection/extension-installer",
+ "version": "0.1.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/infection/extension-installer.git",
+ "reference": "9b351d2910b9a23ab4815542e93d541e0ca0cdcf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/infection/extension-installer/zipball/9b351d2910b9a23ab4815542e93d541e0ca0cdcf",
+ "reference": "9b351d2910b9a23ab4815542e93d541e0ca0cdcf",
+ "shasum": ""
+ },
+ "require": {
+ "composer-plugin-api": "^1.1 || ^2.0"
+ },
+ "require-dev": {
+ "composer/composer": "^1.9 || ^2.0",
+ "friendsofphp/php-cs-fixer": "^2.18, <2.19",
+ "infection/infection": "^0.15.2",
+ "php-coveralls/php-coveralls": "^2.4",
+ "phpstan/extension-installer": "^1.0",
+ "phpstan/phpstan": "^0.12.10",
+ "phpstan/phpstan-phpunit": "^0.12.6",
+ "phpstan/phpstan-strict-rules": "^0.12.2",
+ "phpstan/phpstan-webmozart-assert": "^0.12.2",
+ "phpunit/phpunit": "^9.5",
+ "vimeo/psalm": "^4.8"
+ },
+ "type": "composer-plugin",
+ "extra": {
+ "class": "Infection\\ExtensionInstaller\\Plugin"
+ },
+ "autoload": {
+ "psr-4": {
+ "Infection\\ExtensionInstaller\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Maks Rafalko",
+ "email": "maks.rafalko@gmail.com"
+ }
+ ],
+ "description": "Infection Extension Installer",
+ "support": {
+ "issues": "https://github.com/infection/extension-installer/issues",
+ "source": "https://github.com/infection/extension-installer/tree/0.1.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/infection",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/infection",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2021-10-20T22:08:34+00:00"
+ },
+ {
+ "name": "infection/include-interceptor",
+ "version": "0.2.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/infection/include-interceptor.git",
+ "reference": "0cc76d95a79d9832d74e74492b0a30139904bdf7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/infection/include-interceptor/zipball/0cc76d95a79d9832d74e74492b0a30139904bdf7",
+ "reference": "0cc76d95a79d9832d74e74492b0a30139904bdf7",
+ "shasum": ""
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "^2.16",
+ "infection/infection": "^0.15.0",
+ "phan/phan": "^2.4 || ^3",
+ "php-coveralls/php-coveralls": "^2.2",
+ "phpstan/phpstan": "^0.12.8",
+ "phpunit/phpunit": "^8.5",
+ "vimeo/psalm": "^3.8"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Infection\\StreamWrapper\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Maks Rafalko",
+ "email": "maks.rafalko@gmail.com"
+ }
+ ],
+ "description": "Stream Wrapper: Include Interceptor. Allows to replace included (autoloaded) file with another one.",
+ "support": {
+ "issues": "https://github.com/infection/include-interceptor/issues",
+ "source": "https://github.com/infection/include-interceptor/tree/0.2.5"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/infection",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/infection",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2021-08-09T10:03:57+00:00"
+ },
+ {
+ "name": "infection/infection",
+ "version": "0.26.16",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/infection/infection.git",
+ "reference": "d646aafe530ba21b8479694cd151570c93c72312"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/infection/infection/zipball/d646aafe530ba21b8479694cd151570c93c72312",
+ "reference": "d646aafe530ba21b8479694cd151570c93c72312",
+ "shasum": ""
+ },
+ "require": {
+ "colinodell/json5": "^2.2",
+ "composer-runtime-api": "^2.0",
+ "composer/xdebug-handler": "^2.0 || ^3.0",
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "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.13.2",
+ "ondram/ci-detector": "^4.1.0",
+ "php": "^8.0",
+ "sanmai/later": "^0.1.1",
+ "sanmai/pipeline": "^5.1 || ^6",
+ "sebastian/diff": "^3.0.2 || ^4.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",
+ "webmozart/assert": "^1.3"
+ },
+ "conflict": {
+ "dg/bypass-finals": "<1.4.1",
+ "phpunit/php-code-coverage": ">9 <9.1.4"
+ },
+ "require-dev": {
+ "brianium/paratest": "^6.3",
+ "ext-simplexml": "*",
+ "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"
+ },
+ "bin": [
+ "bin/infection"
+ ],
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Infection\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Maks Rafalko",
+ "email": "maks.rafalko@gmail.com",
+ "homepage": "https://twitter.com/maks_rafalko"
+ },
+ {
+ "name": "Oleg Zhulnev",
+ "homepage": "https://github.com/sidz"
+ },
+ {
+ "name": "Gert de Pagter",
+ "homepage": "https://github.com/BackEndTea"
+ },
+ {
+ "name": "Théo FIDRY",
+ "email": "theo.fidry@gmail.com",
+ "homepage": "https://twitter.com/tfidry"
+ },
+ {
+ "name": "Alexey Kopytko",
+ "email": "alexey@kopytko.com",
+ "homepage": "https://www.alexeykopytko.com"
+ },
+ {
+ "name": "Andreas Möller",
+ "email": "am@localheinz.com",
+ "homepage": "https://localheinz.com"
+ }
+ ],
+ "description": "Infection is a Mutation Testing framework for PHP. The mutation adequacy score can be used to measure the effectiveness of a test set in terms of its ability to detect faults.",
+ "keywords": [
+ "coverage",
+ "mutant",
+ "mutation framework",
+ "mutation testing",
+ "testing",
+ "unit testing"
+ ],
+ "support": {
+ "issues": "https://github.com/infection/infection/issues",
+ "source": "https://github.com/infection/infection/tree/0.26.16"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/infection",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/infection",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2022-10-22T10:07:33+00:00"
+ },
{
"name": "justinrainbow/json-schema",
"version": "5.2.12",
@@ -1880,6 +2274,84 @@
},
"time": "2022-11-12T15:38:23+00:00"
},
+ {
+ "name": "ondram/ci-detector",
+ "version": "4.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/OndraM/ci-detector.git",
+ "reference": "8a4b664e916df82ff26a44709942dfd593fa6f30"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/OndraM/ci-detector/zipball/8a4b664e916df82ff26a44709942dfd593fa6f30",
+ "reference": "8a4b664e916df82ff26a44709942dfd593fa6f30",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0"
+ },
+ "require-dev": {
+ "ergebnis/composer-normalize": "^2.2",
+ "lmc/coding-standard": "^1.3 || ^2.1",
+ "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"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "OndraM\\CiDetector\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ondřej Machulda",
+ "email": "ondrej.machulda@gmail.com"
+ }
+ ],
+ "description": "Detect continuous integration environment and provide unified access to properties of current build",
+ "keywords": [
+ "CircleCI",
+ "Codeship",
+ "Wercker",
+ "adapter",
+ "appveyor",
+ "aws",
+ "aws codebuild",
+ "azure",
+ "azure devops",
+ "azure pipelines",
+ "bamboo",
+ "bitbucket",
+ "buddy",
+ "ci-info",
+ "codebuild",
+ "continuous integration",
+ "continuousphp",
+ "devops",
+ "drone",
+ "github",
+ "gitlab",
+ "interface",
+ "jenkins",
+ "pipelines",
+ "sourcehut",
+ "teamcity",
+ "travis"
+ ],
+ "support": {
+ "issues": "https://github.com/OndraM/ci-detector/issues",
+ "source": "https://github.com/OndraM/ci-detector/tree/4.1.0"
+ },
+ "time": "2021-04-14T09:16:52+00:00"
+ },
{
"name": "phar-io/manifest",
"version": "2.0.3",
@@ -2156,6 +2628,65 @@
},
"time": "2022-10-14T12:47:21+00:00"
},
+ {
+ "name": "phpstan/phpstan",
+ "version": "1.9.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpstan/phpstan.git",
+ "reference": "d03bccee595e2146b7c9d174486b84f4dc61b0f2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/d03bccee595e2146b7c9d174486b84f4dc61b0f2",
+ "reference": "d03bccee595e2146b7c9d174486b84f4dc61b0f2",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2|^8.0"
+ },
+ "conflict": {
+ "phpstan/phpstan-shim": "*"
+ },
+ "bin": [
+ "phpstan",
+ "phpstan.phar"
+ ],
+ "type": "library",
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "PHPStan - PHP Static Analysis Tool",
+ "keywords": [
+ "dev",
+ "static analysis"
+ ],
+ "support": {
+ "issues": "https://github.com/phpstan/phpstan/issues",
+ "source": "https://github.com/phpstan/phpstan/tree/1.9.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/ondrejmirtes",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/phpstan",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-12-17T13:33:52+00:00"
+ },
{
"name": "phpunit/php-code-coverage",
"version": "9.2.19",
@@ -2785,6 +3316,185 @@
},
"time": "2021-07-14T16:46:02+00:00"
},
+ {
+ "name": "rector/rector",
+ "version": "0.15.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/rectorphp/rector.git",
+ "reference": "5bc89fa73d0be2769e02e49a0e924c95b1842093"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/rectorphp/rector/zipball/5bc89fa73d0be2769e02e49a0e924c95b1842093",
+ "reference": "5bc89fa73d0be2769e02e49a0e924c95b1842093",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2|^8.0",
+ "phpstan/phpstan": "^1.9.4"
+ },
+ "conflict": {
+ "rector/rector-doctrine": "*",
+ "rector/rector-downgrade-php": "*",
+ "rector/rector-php-parser": "*",
+ "rector/rector-phpunit": "*",
+ "rector/rector-symfony": "*"
+ },
+ "bin": [
+ "bin/rector"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.14-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Instant Upgrade and Automated Refactoring of any PHP code",
+ "support": {
+ "issues": "https://github.com/rectorphp/rector/issues",
+ "source": "https://github.com/rectorphp/rector/tree/0.15.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/tomasvotruba",
+ "type": "github"
+ }
+ ],
+ "time": "2022-12-24T12:55:36+00:00"
+ },
+ {
+ "name": "sanmai/later",
+ "version": "0.1.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sanmai/later.git",
+ "reference": "9b659fecef2030193fd02402955bc39629d5606f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sanmai/later/zipball/9b659fecef2030193fd02402955bc39629d5606f",
+ "reference": "9b659fecef2030193fd02402955bc39629d5606f",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "^2.13",
+ "infection/infection": ">=0.10.5",
+ "phan/phan": ">=2",
+ "php-coveralls/php-coveralls": "^2.0",
+ "phpstan/phpstan": ">=0.10",
+ "phpunit/phpunit": ">=7.4",
+ "vimeo/psalm": ">=2"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "src/functions.php"
+ ],
+ "psr-4": {
+ "Later\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "Alexey Kopytko",
+ "email": "alexey@kopytko.com"
+ }
+ ],
+ "description": "Later: deferred wrapper object",
+ "support": {
+ "issues": "https://github.com/sanmai/later/issues",
+ "source": "https://github.com/sanmai/later/tree/0.1.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sanmai",
+ "type": "github"
+ }
+ ],
+ "time": "2021-01-02T10:26:44+00:00"
+ },
+ {
+ "name": "sanmai/pipeline",
+ "version": "v6.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sanmai/pipeline.git",
+ "reference": "929b115ca58d62b6b2574702df1ebde4562c7c43"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sanmai/pipeline/zipball/929b115ca58d62b6b2574702df1ebde4562c7c43",
+ "reference": "929b115ca58d62b6b2574702df1ebde4562c7c43",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0"
+ },
+ "require-dev": {
+ "ergebnis/composer-normalize": "^2.8",
+ "friendsofphp/php-cs-fixer": "^3",
+ "infection/infection": ">=0.10.5",
+ "league/pipeline": "^1.0 || ^0.3",
+ "phan/phan": ">=1.1",
+ "php-coveralls/php-coveralls": "^2.4.1",
+ "phpstan/phpstan": ">=0.10",
+ "phpunit/phpunit": "^7.4 || ^8.1 || ^9.4",
+ "vimeo/psalm": ">=2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "v6.x-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/functions.php"
+ ],
+ "psr-4": {
+ "Pipeline\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "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",
@@ -5043,6 +5753,145 @@
],
"time": "2022-10-10T09:34:08+00:00"
},
+ {
+ "name": "thecodingmachine/safe",
+ "version": "v2.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/thecodingmachine/safe.git",
+ "reference": "e788f3d09dcd36f806350aedb77eac348fafadd3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/thecodingmachine/safe/zipball/e788f3d09dcd36f806350aedb77eac348fafadd3",
+ "reference": "e788f3d09dcd36f806350aedb77eac348fafadd3",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^8.0"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "^1.5",
+ "phpunit/phpunit": "^9.5",
+ "squizlabs/php_codesniffer": "^3.2",
+ "thecodingmachine/phpstan-strict-rules": "^1.0"
+ },
+ "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",
+ "generated/bzip2.php",
+ "generated/calendar.php",
+ "generated/classobj.php",
+ "generated/com.php",
+ "generated/cubrid.php",
+ "generated/curl.php",
+ "generated/datetime.php",
+ "generated/dir.php",
+ "generated/eio.php",
+ "generated/errorfunc.php",
+ "generated/exec.php",
+ "generated/fileinfo.php",
+ "generated/filesystem.php",
+ "generated/filter.php",
+ "generated/fpm.php",
+ "generated/ftp.php",
+ "generated/funchand.php",
+ "generated/gettext.php",
+ "generated/gmp.php",
+ "generated/gnupg.php",
+ "generated/hash.php",
+ "generated/ibase.php",
+ "generated/ibmDb2.php",
+ "generated/iconv.php",
+ "generated/image.php",
+ "generated/imap.php",
+ "generated/info.php",
+ "generated/inotify.php",
+ "generated/json.php",
+ "generated/ldap.php",
+ "generated/libxml.php",
+ "generated/lzf.php",
+ "generated/mailparse.php",
+ "generated/mbstring.php",
+ "generated/misc.php",
+ "generated/mysql.php",
+ "generated/network.php",
+ "generated/oci8.php",
+ "generated/opcache.php",
+ "generated/openssl.php",
+ "generated/outcontrol.php",
+ "generated/pcntl.php",
+ "generated/pcre.php",
+ "generated/pgsql.php",
+ "generated/posix.php",
+ "generated/ps.php",
+ "generated/pspell.php",
+ "generated/readline.php",
+ "generated/rpminfo.php",
+ "generated/rrd.php",
+ "generated/sem.php",
+ "generated/session.php",
+ "generated/shmop.php",
+ "generated/sockets.php",
+ "generated/sodium.php",
+ "generated/solr.php",
+ "generated/spl.php",
+ "generated/sqlsrv.php",
+ "generated/ssdeep.php",
+ "generated/ssh2.php",
+ "generated/stream.php",
+ "generated/strings.php",
+ "generated/swoole.php",
+ "generated/uodbc.php",
+ "generated/uopz.php",
+ "generated/url.php",
+ "generated/var.php",
+ "generated/xdiff.php",
+ "generated/xml.php",
+ "generated/xmlrpc.php",
+ "generated/yaml.php",
+ "generated/yaz.php",
+ "generated/zip.php",
+ "generated/zlib.php"
+ ],
+ "classmap": [
+ "lib/DateTime.php",
+ "lib/DateTimeImmutable.php",
+ "lib/Exceptions/",
+ "deprecated/Exceptions/",
+ "generated/Exceptions/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "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"
+ },
+ "time": "2022-10-07T14:02:17+00:00"
+ },
{
"name": "theseer/tokenizer",
"version": "1.2.1",
diff --git a/infection.json b/infection.json
new file mode 100644
index 0000000..f6e161c
--- /dev/null
+++ b/infection.json
@@ -0,0 +1,17 @@
+{
+ "ignoreMsiWithNoMutations": true,
+ "logs": {
+ "text": ".build/infection/infection-log.txt"
+ },
+ "minCoveredMsi": 84,
+ "minMsi": 79,
+ "phpUnit": {
+ "configDir": "test\/Unit"
+ },
+ "source": {
+ "directories": [
+ "src"
+ ]
+ },
+ "timeout": 10
+}
diff --git a/psalm-baseline.xml b/psalm-baseline.xml
index 560602f..596d6eb 100644
--- a/psalm-baseline.xml
+++ b/psalm-baseline.xml
@@ -1,5 +1,5 @@
-
+
$value
diff --git a/psalm.xml b/psalm.xml
index 12df516..adb7fb4 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -17,6 +17,7 @@
+
diff --git a/rector.php b/rector.php
new file mode 100644
index 0000000..9abc405
--- /dev/null
+++ b/rector.php
@@ -0,0 +1,28 @@
+cacheDirectory(__DIR__ . '/.build/rector/');
+
+ $rectorConfig->import(__DIR__ . '/vendor/fakerphp/faker/rector-migrate.php');
+
+ $rectorConfig->paths([
+ __DIR__ . '/src/',
+ __DIR__ . '/test/',
+ ]);
+
+ $rectorConfig->phpVersion(Core\ValueObject\PhpVersion::PHP_80);
+};