diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml
index a29ac18..c2fd5ee 100644
--- a/.github/workflows/phpunit.yml
+++ b/.github/workflows/phpunit.yml
@@ -3,6 +3,8 @@ on: push
jobs:
phpunit:
runs-on: ubuntu-latest
+ env:
+ IS_CI_TEST: true
steps:
- uses: actions/checkout@v1
- uses: shivammathur/setup-php@v2
diff --git a/.gitignore b/.gitignore
index 4da6094..99cb968 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
vendor
var
+!var/tests/repo
!var/**/.gitkeep
.phpunit.result.cache
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..95cd4ff
--- /dev/null
+++ b/README.md
@@ -0,0 +1,11 @@
+# PHPCS Documentation Generator
+
+Note: this currently works only with the PHPCompatibility standard.
+
+## Usage
+
+Copy the `generator.xml.dist` template to `generator.xml` and add your sources and standards.
+
+```sh
+bin/phpcsdocs generate
+```
diff --git a/composer.json b/composer.json
index 1242441..c381f2c 100644
--- a/composer.json
+++ b/composer.json
@@ -6,9 +6,12 @@
"danielstjules/stringy": "^3.1",
"roave/better-reflection": "^4.12",
"phpdocumentor/reflection-docblock": "^5.2",
- "ext-simplexml": "*",
"symfony/filesystem": "^5.2",
- "symfony/process": "^5.2"
+ "symfony/process": "^5.2",
+ "nikic/php-parser": "4.6.*",
+ "ext-simplexml": "*",
+ "ext-dom": "*",
+ "ext-libxml": "*"
},
"autoload": {
"psr-4": {
@@ -17,6 +20,6 @@
}
},
"require-dev": {
- "phpunit/phpunit": "^9.5"
+ "phpunit/phpunit": "^9.0"
}
}
diff --git a/composer.lock b/composer.lock
index 89eee70..fad8cb9 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": "d1e357dd79e21303096f74a1a97631ed",
+ "content-hash": "27502a4c19ce2892bc1f63c5028e2b76",
"packages": [
{
"name": "beberlei/assert",
@@ -180,16 +180,16 @@
},
{
"name": "nikic/php-parser",
- "version": "v4.10.4",
+ "version": "v4.6.0",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
- "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e"
+ "reference": "c346bbfafe2ff60680258b631afb730d186ed864"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/c6d052fc58cb876152f89f532b95a8d7907e7f0e",
- "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/c346bbfafe2ff60680258b631afb730d186ed864",
+ "reference": "c346bbfafe2ff60680258b631afb730d186ed864",
"shasum": ""
},
"require": {
@@ -197,8 +197,8 @@
"php": ">=7.0"
},
"require-dev": {
- "ircmaxell/php-yacc": "^0.0.7",
- "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
+ "ircmaxell/php-yacc": "0.0.5",
+ "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0"
},
"bin": [
"bin/php-parse"
@@ -206,7 +206,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.9-dev"
+ "dev-master": "4.3-dev"
}
},
"autoload": {
@@ -230,9 +230,9 @@
],
"support": {
"issues": "https://github.com/nikic/PHP-Parser/issues",
- "source": "https://github.com/nikic/PHP-Parser/tree/v4.10.4"
+ "source": "https://github.com/nikic/PHP-Parser/tree/v4.6.0"
},
- "time": "2020-12-20T10:01:03+00:00"
+ "time": "2020-07-02T17:12:47+00:00"
},
{
"name": "opis/closure",
@@ -763,26 +763,26 @@
},
{
"name": "roave/signature",
- "version": "1.3.0",
+ "version": "1.4.0",
"source": {
"type": "git",
"url": "https://github.com/Roave/Signature.git",
- "reference": "bbbcc317dfe3a750e27231c5d2130153aa4c41b3"
+ "reference": "5b5bb9499cfbcc78d9f472e03af1e97e4341ec7c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Roave/Signature/zipball/bbbcc317dfe3a750e27231c5d2130153aa4c41b3",
- "reference": "bbbcc317dfe3a750e27231c5d2130153aa4c41b3",
+ "url": "https://api.github.com/repos/Roave/Signature/zipball/5b5bb9499cfbcc78d9f472e03af1e97e4341ec7c",
+ "reference": "5b5bb9499cfbcc78d9f472e03af1e97e4341ec7c",
"shasum": ""
},
"require": {
- "php": "7.4.*"
+ "php": "7.4.*|8.0.*"
},
"require-dev": {
- "doctrine/coding-standard": "^8.1",
- "infection/infection": "^0.17.5",
- "phpunit/phpunit": "^9.3",
- "vimeo/psalm": "^3.16"
+ "doctrine/coding-standard": "^8.2",
+ "infection/infection": "^0.20.2",
+ "phpunit/phpunit": "^9.5.1",
+ "vimeo/psalm": "^4.4"
},
"type": "library",
"autoload": {
@@ -797,22 +797,22 @@
"description": "Sign and verify stuff",
"support": {
"issues": "https://github.com/Roave/Signature/issues",
- "source": "https://github.com/Roave/Signature/tree/1.3.0"
+ "source": "https://github.com/Roave/Signature/tree/1.4.0"
},
- "time": "2020-10-01T08:35:57+00:00"
+ "time": "2021-01-25T09:39:37+00:00"
},
{
"name": "symfony/console",
- "version": "v5.2.1",
+ "version": "v5.2.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "47c02526c532fb381374dab26df05e7313978976"
+ "reference": "d62ec79478b55036f65e2602e282822b8eaaff0a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/47c02526c532fb381374dab26df05e7313978976",
- "reference": "47c02526c532fb381374dab26df05e7313978976",
+ "url": "https://api.github.com/repos/symfony/console/zipball/d62ec79478b55036f65e2602e282822b8eaaff0a",
+ "reference": "d62ec79478b55036f65e2602e282822b8eaaff0a",
"shasum": ""
},
"require": {
@@ -871,7 +871,7 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony Console Component",
+ "description": "Eases the creation of beautiful and testable command line interfaces",
"homepage": "https://symfony.com",
"keywords": [
"cli",
@@ -880,7 +880,7 @@
"terminal"
],
"support": {
- "source": "https://github.com/symfony/console/tree/v5.2.1"
+ "source": "https://github.com/symfony/console/tree/v5.2.2"
},
"funding": [
{
@@ -896,20 +896,20 @@
"type": "tidelift"
}
],
- "time": "2020-12-18T08:03:05+00:00"
+ "time": "2021-01-27T10:15:41+00:00"
},
{
"name": "symfony/filesystem",
- "version": "v5.2.1",
+ "version": "v5.2.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
- "reference": "fa8f8cab6b65e2d99a118e082935344c5ba8c60d"
+ "reference": "262d033b57c73e8b59cd6e68a45c528318b15038"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/fa8f8cab6b65e2d99a118e082935344c5ba8c60d",
- "reference": "fa8f8cab6b65e2d99a118e082935344c5ba8c60d",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/262d033b57c73e8b59cd6e68a45c528318b15038",
+ "reference": "262d033b57c73e8b59cd6e68a45c528318b15038",
"shasum": ""
},
"require": {
@@ -939,10 +939,10 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony Filesystem Component",
+ "description": "Provides basic utilities for the filesystem",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/filesystem/tree/v5.2.1"
+ "source": "https://github.com/symfony/filesystem/tree/v5.2.2"
},
"funding": [
{
@@ -958,7 +958,7 @@
"type": "tidelift"
}
],
- "time": "2020-11-30T17:05:38+00:00"
+ "time": "2021-01-27T10:01:46+00:00"
},
{
"name": "symfony/polyfill-ctype",
@@ -1448,16 +1448,16 @@
},
{
"name": "symfony/process",
- "version": "v5.2.1",
+ "version": "v5.2.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
- "reference": "bd8815b8b6705298beaa384f04fabd459c10bedd"
+ "reference": "313a38f09c77fbcdc1d223e57d368cea76a2fd2f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/bd8815b8b6705298beaa384f04fabd459c10bedd",
- "reference": "bd8815b8b6705298beaa384f04fabd459c10bedd",
+ "url": "https://api.github.com/repos/symfony/process/zipball/313a38f09c77fbcdc1d223e57d368cea76a2fd2f",
+ "reference": "313a38f09c77fbcdc1d223e57d368cea76a2fd2f",
"shasum": ""
},
"require": {
@@ -1487,10 +1487,10 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony Process Component",
+ "description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/process/tree/v5.2.1"
+ "source": "https://github.com/symfony/process/tree/v5.2.2"
},
"funding": [
{
@@ -1506,7 +1506,7 @@
"type": "tidelift"
}
],
- "time": "2020-12-08T17:03:37+00:00"
+ "time": "2021-01-27T10:15:41+00:00"
},
{
"name": "symfony/service-contracts",
@@ -1589,16 +1589,16 @@
},
{
"name": "symfony/string",
- "version": "v5.2.1",
+ "version": "v5.2.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
- "reference": "5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed"
+ "reference": "c95468897f408dd0aca2ff582074423dd0455122"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/string/zipball/5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed",
- "reference": "5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed",
+ "url": "https://api.github.com/repos/symfony/string/zipball/c95468897f408dd0aca2ff582074423dd0455122",
+ "reference": "c95468897f408dd0aca2ff582074423dd0455122",
"shasum": ""
},
"require": {
@@ -1641,7 +1641,7 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony String component",
+ "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way",
"homepage": "https://symfony.com",
"keywords": [
"grapheme",
@@ -1652,7 +1652,7 @@
"utf8"
],
"support": {
- "source": "https://github.com/symfony/string/tree/v5.2.1"
+ "source": "https://github.com/symfony/string/tree/v5.2.2"
},
"funding": [
{
@@ -1668,7 +1668,7 @@
"type": "tidelift"
}
],
- "time": "2020-12-05T07:33:16+00:00"
+ "time": "2021-01-25T15:14:59+00:00"
},
{
"name": "webmozart/assert",
@@ -1854,29 +1854,28 @@
},
{
"name": "phar-io/manifest",
- "version": "2.0.1",
+ "version": "1.0.3",
"source": {
"type": "git",
"url": "https://github.com/phar-io/manifest.git",
- "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133"
+ "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phar-io/manifest/zipball/85265efd3af7ba3ca4b2a2c34dbfc5788dd29133",
- "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133",
+ "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
+ "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-phar": "*",
- "ext-xmlwriter": "*",
- "phar-io/version": "^3.0.1",
- "php": "^7.2 || ^8.0"
+ "phar-io/version": "^2.0",
+ "php": "^5.6 || ^7.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.0.x-dev"
+ "dev-master": "1.0.x-dev"
}
},
"autoload": {
@@ -1910,24 +1909,24 @@
"issues": "https://github.com/phar-io/manifest/issues",
"source": "https://github.com/phar-io/manifest/tree/master"
},
- "time": "2020-06-27T14:33:11+00:00"
+ "time": "2018-07-08T19:23:20+00:00"
},
{
"name": "phar-io/version",
- "version": "3.0.4",
+ "version": "2.0.1",
"source": {
"type": "git",
"url": "https://github.com/phar-io/version.git",
- "reference": "e4782611070e50613683d2b9a57730e9a3ba5451"
+ "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phar-io/version/zipball/e4782611070e50613683d2b9a57730e9a3ba5451",
- "reference": "e4782611070e50613683d2b9a57730e9a3ba5451",
+ "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6",
+ "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6",
"shasum": ""
},
"require": {
- "php": "^7.2 || ^8.0"
+ "php": "^5.6 || ^7.0"
},
"type": "library",
"autoload": {
@@ -1959,9 +1958,9 @@
"description": "Library for handling version information and constraints",
"support": {
"issues": "https://github.com/phar-io/version/issues",
- "source": "https://github.com/phar-io/version/tree/3.0.4"
+ "source": "https://github.com/phar-io/version/tree/master"
},
- "time": "2020-12-13T23:18:30+00:00"
+ "time": "2018-07-08T19:19:57+00:00"
},
{
"name": "phpspec/prophecy",
@@ -2032,35 +2031,32 @@
},
{
"name": "phpunit/php-code-coverage",
- "version": "9.2.5",
+ "version": "8.0.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
- "reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1"
+ "reference": "ca6647ffddd2add025ab3f21644a441d7c146cdc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f3e026641cc91909d421802dd3ac7827ebfd97e1",
- "reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca6647ffddd2add025ab3f21644a441d7c146cdc",
+ "reference": "ca6647ffddd2add025ab3f21644a441d7c146cdc",
"shasum": ""
},
"require": {
"ext-dom": "*",
- "ext-libxml": "*",
"ext-xmlwriter": "*",
- "nikic/php-parser": "^4.10.2",
- "php": ">=7.3",
- "phpunit/php-file-iterator": "^3.0.3",
- "phpunit/php-text-template": "^2.0.2",
- "sebastian/code-unit-reverse-lookup": "^2.0.2",
- "sebastian/complexity": "^2.0",
- "sebastian/environment": "^5.1.2",
- "sebastian/lines-of-code": "^1.0.3",
- "sebastian/version": "^3.0.1",
- "theseer/tokenizer": "^1.2.0"
+ "php": "^7.3",
+ "phpunit/php-file-iterator": "^3.0",
+ "phpunit/php-text-template": "^2.0",
+ "phpunit/php-token-stream": "^4.0",
+ "sebastian/code-unit-reverse-lookup": "^2.0",
+ "sebastian/environment": "^5.0",
+ "sebastian/version": "^3.0",
+ "theseer/tokenizer": "^1.1.3"
},
"require-dev": {
- "phpunit/phpunit": "^9.3"
+ "phpunit/phpunit": "^9.0"
},
"suggest": {
"ext-pcov": "*",
@@ -2069,7 +2065,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "9.2-dev"
+ "dev-master": "8.0-dev"
}
},
"autoload": {
@@ -2097,7 +2093,7 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
- "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.5"
+ "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/8.0.2"
},
"funding": [
{
@@ -2105,7 +2101,7 @@
"type": "github"
}
],
- "time": "2020-11-28T06:44:49+00:00"
+ "time": "2020-05-23T08:02:54+00:00"
},
{
"name": "phpunit/php-file-iterator",
@@ -2349,72 +2345,35 @@
"time": "2020-10-26T13:16:10+00:00"
},
{
- "name": "phpunit/phpunit",
- "version": "9.5.1",
+ "name": "phpunit/php-token-stream",
+ "version": "4.0.4",
"source": {
"type": "git",
- "url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "e7bdf4085de85a825f4424eae52c99a1cec2f360"
+ "url": "https://github.com/sebastianbergmann/php-token-stream.git",
+ "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e7bdf4085de85a825f4424eae52c99a1cec2f360",
- "reference": "e7bdf4085de85a825f4424eae52c99a1cec2f360",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/a853a0e183b9db7eed023d7933a858fa1c8d25a3",
+ "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3",
"shasum": ""
},
"require": {
- "doctrine/instantiator": "^1.3.1",
- "ext-dom": "*",
- "ext-json": "*",
- "ext-libxml": "*",
- "ext-mbstring": "*",
- "ext-xml": "*",
- "ext-xmlwriter": "*",
- "myclabs/deep-copy": "^1.10.1",
- "phar-io/manifest": "^2.0.1",
- "phar-io/version": "^3.0.2",
- "php": ">=7.3",
- "phpspec/prophecy": "^1.12.1",
- "phpunit/php-code-coverage": "^9.2.3",
- "phpunit/php-file-iterator": "^3.0.5",
- "phpunit/php-invoker": "^3.1.1",
- "phpunit/php-text-template": "^2.0.3",
- "phpunit/php-timer": "^5.0.2",
- "sebastian/cli-parser": "^1.0.1",
- "sebastian/code-unit": "^1.0.6",
- "sebastian/comparator": "^4.0.5",
- "sebastian/diff": "^4.0.3",
- "sebastian/environment": "^5.1.3",
- "sebastian/exporter": "^4.0.3",
- "sebastian/global-state": "^5.0.1",
- "sebastian/object-enumerator": "^4.0.3",
- "sebastian/resource-operations": "^3.0.3",
- "sebastian/type": "^2.3",
- "sebastian/version": "^3.0.2"
+ "ext-tokenizer": "*",
+ "php": "^7.3 || ^8.0"
},
"require-dev": {
- "ext-pdo": "*",
- "phpspec/prophecy-phpunit": "^2.0.1"
- },
- "suggest": {
- "ext-soap": "*",
- "ext-xdebug": "*"
+ "phpunit/phpunit": "^9.0"
},
- "bin": [
- "phpunit"
- ],
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "9.5-dev"
+ "dev-master": "4.0-dev"
}
},
"autoload": {
"classmap": [
"src/"
- ],
- "files": [
- "src/Framework/Assert/Functions.php"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -2424,62 +2383,93 @@
"authors": [
{
"name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
+ "email": "sebastian@phpunit.de"
}
],
- "description": "The PHP Unit Testing framework.",
- "homepage": "https://phpunit.de/",
+ "description": "Wrapper around PHP's tokenizer extension.",
+ "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
"keywords": [
- "phpunit",
- "testing",
- "xunit"
+ "tokenizer"
],
"support": {
- "issues": "https://github.com/sebastianbergmann/phpunit/issues",
- "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.1"
+ "issues": "https://github.com/sebastianbergmann/php-token-stream/issues",
+ "source": "https://github.com/sebastianbergmann/php-token-stream/tree/master"
},
"funding": [
- {
- "url": "https://phpunit.de/donate.html",
- "type": "custom"
- },
{
"url": "https://github.com/sebastianbergmann",
"type": "github"
}
],
- "time": "2021-01-17T07:42:25+00:00"
+ "abandoned": true,
+ "time": "2020-08-04T08:28:15+00:00"
},
{
- "name": "sebastian/cli-parser",
- "version": "1.0.1",
+ "name": "phpunit/phpunit",
+ "version": "9.2.6",
"source": {
"type": "git",
- "url": "https://github.com/sebastianbergmann/cli-parser.git",
- "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2"
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
+ "reference": "1c6a9e4312e209e659f1fce3ce88dd197c2448f6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2",
- "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1c6a9e4312e209e659f1fce3ce88dd197c2448f6",
+ "reference": "1c6a9e4312e209e659f1fce3ce88dd197c2448f6",
"shasum": ""
},
"require": {
- "php": ">=7.3"
+ "doctrine/instantiator": "^1.3.1",
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-xml": "*",
+ "ext-xmlwriter": "*",
+ "myclabs/deep-copy": "^1.9.5",
+ "phar-io/manifest": "^1.0.3",
+ "phar-io/version": "^2.0.1",
+ "php": "^7.3",
+ "phpspec/prophecy": "^1.10.3",
+ "phpunit/php-code-coverage": "^8.0.2",
+ "phpunit/php-file-iterator": "^3.0.3",
+ "phpunit/php-invoker": "^3.0.2",
+ "phpunit/php-text-template": "^2.0.2",
+ "phpunit/php-timer": "^5.0.1",
+ "sebastian/code-unit": "^1.0.5",
+ "sebastian/comparator": "^4.0.3",
+ "sebastian/diff": "^4.0.1",
+ "sebastian/environment": "^5.1.2",
+ "sebastian/exporter": "^4.0.2",
+ "sebastian/global-state": "^4.0",
+ "sebastian/object-enumerator": "^4.0.2",
+ "sebastian/resource-operations": "^3.0.2",
+ "sebastian/type": "^2.1.1",
+ "sebastian/version": "^3.0.1"
},
"require-dev": {
- "phpunit/phpunit": "^9.3"
+ "ext-pdo": "*",
+ "phpspec/prophecy-phpunit": "^2.0"
+ },
+ "suggest": {
+ "ext-soap": "*",
+ "ext-xdebug": "*"
},
+ "bin": [
+ "phpunit"
+ ],
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0-dev"
+ "dev-master": "9.2-dev"
}
},
"autoload": {
"classmap": [
"src/"
+ ],
+ "files": [
+ "src/Framework/Assert/Functions.php"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -2493,19 +2483,28 @@
"role": "lead"
}
],
- "description": "Library for parsing CLI options",
- "homepage": "https://github.com/sebastianbergmann/cli-parser",
+ "description": "The PHP Unit Testing framework.",
+ "homepage": "https://phpunit.de/",
+ "keywords": [
+ "phpunit",
+ "testing",
+ "xunit"
+ ],
"support": {
- "issues": "https://github.com/sebastianbergmann/cli-parser/issues",
- "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1"
+ "issues": "https://github.com/sebastianbergmann/phpunit/issues",
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/9.2.6"
},
"funding": [
+ {
+ "url": "https://phpunit.de/donate.html",
+ "type": "custom"
+ },
{
"url": "https://github.com/sebastianbergmann",
"type": "github"
}
],
- "time": "2020-09-28T06:08:49+00:00"
+ "time": "2020-07-13T17:55:55+00:00"
},
{
"name": "sebastian/code-unit",
@@ -2692,63 +2691,6 @@
],
"time": "2020-10-26T15:49:45+00:00"
},
- {
- "name": "sebastian/complexity",
- "version": "2.0.2",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/complexity.git",
- "reference": "739b35e53379900cc9ac327b2147867b8b6efd88"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88",
- "reference": "739b35e53379900cc9ac327b2147867b8b6efd88",
- "shasum": ""
- },
- "require": {
- "nikic/php-parser": "^4.7",
- "php": ">=7.3"
- },
- "require-dev": {
- "phpunit/phpunit": "^9.3"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "Library for calculating the complexity of PHP code units",
- "homepage": "https://github.com/sebastianbergmann/complexity",
- "support": {
- "issues": "https://github.com/sebastianbergmann/complexity/issues",
- "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2020-10-26T15:52:27+00:00"
- },
{
"name": "sebastian/diff",
"version": "4.0.4",
@@ -2957,26 +2899,26 @@
},
{
"name": "sebastian/global-state",
- "version": "5.0.2",
+ "version": "4.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/global-state.git",
- "reference": "a90ccbddffa067b51f574dea6eb25d5680839455"
+ "reference": "bdb1e7c79e592b8c82cb1699be3c8743119b8a72"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/a90ccbddffa067b51f574dea6eb25d5680839455",
- "reference": "a90ccbddffa067b51f574dea6eb25d5680839455",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bdb1e7c79e592b8c82cb1699be3c8743119b8a72",
+ "reference": "bdb1e7c79e592b8c82cb1699be3c8743119b8a72",
"shasum": ""
},
"require": {
- "php": ">=7.3",
+ "php": "^7.3",
"sebastian/object-reflector": "^2.0",
"sebastian/recursion-context": "^4.0"
},
"require-dev": {
"ext-dom": "*",
- "phpunit/phpunit": "^9.3"
+ "phpunit/phpunit": "^9.0"
},
"suggest": {
"ext-uopz": "*"
@@ -2984,7 +2926,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "5.0-dev"
+ "dev-master": "4.0-dev"
}
},
"autoload": {
@@ -3009,72 +2951,9 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/global-state/issues",
- "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.2"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2020-10-26T15:55:19+00:00"
- },
- {
- "name": "sebastian/lines-of-code",
- "version": "1.0.3",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/lines-of-code.git",
- "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc",
- "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc",
- "shasum": ""
- },
- "require": {
- "nikic/php-parser": "^4.6",
- "php": ">=7.3"
- },
- "require-dev": {
- "phpunit/phpunit": "^9.3"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0-dev"
- }
+ "source": "https://github.com/sebastianbergmann/global-state/tree/master"
},
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "Library for counting the lines of code in PHP source code",
- "homepage": "https://github.com/sebastianbergmann/lines-of-code",
- "support": {
- "issues": "https://github.com/sebastianbergmann/lines-of-code/issues",
- "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2020-11-28T06:42:11+00:00"
+ "time": "2020-02-07T06:11:37+00:00"
},
{
"name": "sebastian/object-enumerator",
@@ -3472,7 +3351,9 @@
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
- "ext-simplexml": "*"
+ "ext-simplexml": "*",
+ "ext-dom": "*",
+ "ext-libxml": "*"
},
"platform-dev": [],
"plugin-api-version": "2.0.0"
diff --git a/config/di.php b/config/di.php
index 85b2b4e..b51af2d 100644
--- a/config/di.php
+++ b/config/di.php
@@ -1,15 +1,18 @@
DI\autowire(GithubCodeRepository::class),
DocGenerator::class => DI\autowire(MarkdownGenerator::class),
SniffFinder::class => DI\autowire(FilesystemSniffFinder::class),
+ ConfigurationRepository::class => DI\factory(function () {
+ return new XmlConfigurationRepository(new Folder(__DIR__ . '/../'));
+ })
];
diff --git a/generator.xml.dist b/generator.xml.dist
new file mode 100644
index 0000000..647bea3
--- /dev/null
+++ b/generator.xml.dist
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/src/CodeRepository/CodeRepository.php b/src/CodeRepository/CodeRepository.php
index d132f32..1ff2784 100644
--- a/src/CodeRepository/CodeRepository.php
+++ b/src/CodeRepository/CodeRepository.php
@@ -3,11 +3,12 @@
namespace App\CodeRepository;
+use App\Configuration\Value\Source;
use App\Value\Folder;
interface CodeRepository
{
public const CODE_DOWNLOAD_PATH = 'var/repos/';
- public function downloadCode(string $repoName): Folder;
+ public function getFolder(Source $source): Folder;
}
diff --git a/src/CodeRepository/CodeRepositoryFactory.php b/src/CodeRepository/CodeRepositoryFactory.php
new file mode 100644
index 0000000..26f6ab9
--- /dev/null
+++ b/src/CodeRepository/CodeRepositoryFactory.php
@@ -0,0 +1,22 @@
+runProcess($this->getCloneOrPullProcess($source->getLocalFolder(), $source->getPath()));
+ $this->runProcess($this->getComposerInstallProcess($source->getLocalFolder()));
- $this->runProcess($this->getCloneOrPullProcess($repoPath, $repoName));
- $this->runProcess($this->getComposerInstallProcess($repoPath));
-
- return $repoPath;
+ return $source->getLocalFolder();
}
private function runProcess(Process $process): void
@@ -28,21 +27,21 @@ private function runProcess(Process $process): void
}
}
- private function getCloneOrPullProcess(Folder $repoPath, string $repoName): Process
+ private function getCloneOrPullProcess(Folder $localPath, string $sourcePath): Process
{
- if (!is_dir((string)$repoPath)) {
+ if (!is_dir((string)$localPath)) {
return new Process([
'git',
'clone',
- 'git@github.com:' . $repoName,
- $repoPath
+ $sourcePath,
+ (string)$localPath
]);
}
return new Process([
'git',
'-C',
- $repoPath,
+ (string)$localPath,
'pull'
]);
}
diff --git a/src/CodeRepository/LocalCodeRepository.php b/src/CodeRepository/LocalCodeRepository.php
new file mode 100644
index 0000000..62594fa
--- /dev/null
+++ b/src/CodeRepository/LocalCodeRepository.php
@@ -0,0 +1,38 @@
+runProcess($this->getComposerInstallProcess($source->getLocalFolder()));
+
+ return $source->getLocalFolder();
+ }
+
+ private function runProcess(Process $process): void
+ {
+ $process->run();
+
+ if (!$process->isSuccessful()) {
+ throw new ProcessFailedException($process);
+ }
+ }
+
+ private function getComposerInstallProcess(Folder $repoPath): Process
+ {
+ return new Process([
+ 'composer',
+ 'install',
+ '-d',
+ $repoPath
+ ]);
+ }
+}
diff --git a/src/Configuration/ConfigurationRepository.php b/src/Configuration/ConfigurationRepository.php
new file mode 100644
index 0000000..959ff32
--- /dev/null
+++ b/src/Configuration/ConfigurationRepository.php
@@ -0,0 +1,11 @@
+inArray(['markdown'], sprintf('Invalid generator format "%s"', $format));
+
+ Assert::thatAll($sources)
+ ->isInstanceOf(Source::class);
+
+ $this->format = $format;
+ $this->sources = $sources;
+ }
+
+ public function getFormat(): string
+ {
+ return $this->format;
+ }
+
+ /**
+ * @return Source[]
+ */
+ public function getSources(): array
+ {
+ return $this->sources;
+ }
+}
diff --git a/src/Configuration/Value/Source.php b/src/Configuration/Value/Source.php
new file mode 100644
index 0000000..c7fa46b
--- /dev/null
+++ b/src/Configuration/Value/Source.php
@@ -0,0 +1,68 @@
+path = $path;
+ $this->standards = $standards;
+
+ if (preg_match('/([^.\/]+)\.git$/', $path, $matches)) {
+ $this->localFolder = $this->createLocalFolder(CodeRepository::CODE_DOWNLOAD_PATH . $matches[1]);
+ $this->type = self::TYPE_GIT;
+ return;
+ }
+
+ $this->localFolder = $this->createLocalFolder($path);
+ }
+
+ private function createLocalFolder(string $path): Folder
+ {
+ $path = s($path)->ensureRight('/');
+ return new Folder((string)$path);
+ }
+
+ public function getPath(): string
+ {
+ return $this->path;
+ }
+
+ public function getLocalFolder(): Folder
+ {
+ return $this->localFolder;
+ }
+
+ /**
+ * @return Standard[]
+ */
+ public function getStandards(): array
+ {
+ return $this->standards;
+ }
+
+ public function getType(): string
+ {
+ return $this->type;
+ }
+}
diff --git a/src/Configuration/Value/Standard.php b/src/Configuration/Value/Standard.php
new file mode 100644
index 0000000..af4c35d
--- /dev/null
+++ b/src/Configuration/Value/Standard.php
@@ -0,0 +1,24 @@
+notBlank();
+
+ $this->path = $path;
+ }
+
+ public function getPath(): string
+ {
+ return $this->path;
+ }
+}
diff --git a/src/Configuration/XmlConfigurationRepository.php b/src/Configuration/XmlConfigurationRepository.php
new file mode 100644
index 0000000..7b52817
--- /dev/null
+++ b/src/Configuration/XmlConfigurationRepository.php
@@ -0,0 +1,82 @@
+root = $root;
+ }
+
+ public function getConfig(): Configuration
+ {
+ $paths = [$this->root . 'generator.xml', $this->root . 'generator.xml.dist'];
+ foreach ($paths as $path) {
+ if (file_exists($path)) {
+ return $this->parse($path);
+ }
+ }
+
+ throw new RuntimeException(
+ sprintf('Could not find a configuration file in any of these paths: %s', implode(',', $paths))
+ );
+ }
+
+ private function parse(string $path): Configuration
+ {
+ $dom = new DOMDocument;
+ $dom->load($path);
+
+ set_error_handler(function (int $number, string $error) use ($path) {
+ throw new RuntimeException(
+ sprintf("The configuration file %s is invalid.\n%s", $path, $error)
+ );
+ });
+ $dom->schemaValidate(__DIR__ . '/generator.xsd');
+ restore_error_handler();
+
+ $xml = new SimpleXMLElement(file_get_contents($path));
+
+ return new Configuration(
+ (string)$xml['format'],
+ $this->getSources($xml),
+ );
+ }
+
+ /**
+ * @return Source[]
+ */
+ private function getSources(SimpleXMLElement $xml): array
+ {
+ return array_map(function (SimpleXMLElement $source): Source {
+ return new Source(
+ (string)$source['path'],
+ $this->getStandards($source)
+ );
+ }, $xml->xpath('source'));
+ }
+
+ /**
+ * @return Standard[]
+ */
+ private function getStandards(SimpleXMLElement $xml): array
+ {
+ return array_map(function (SimpleXMLElement $standard): Standard {
+ return new Standard(
+ (string)$standard['path']
+ );
+ }, $xml->xpath('standard'));
+ }
+}
diff --git a/src/Configuration/generator.xsd b/src/Configuration/generator.xsd
new file mode 100644
index 0000000..fe6c4af
--- /dev/null
+++ b/src/Configuration/generator.xsd
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Generator/MarkdownGenerator.php b/src/Generator/MarkdownGenerator.php
index b329433..2baaa73 100644
--- a/src/Generator/MarkdownGenerator.php
+++ b/src/Generator/MarkdownGenerator.php
@@ -27,8 +27,8 @@ public function createSniffDoc(Sniff $sniff): string
{$this->getViolations($sniff->getViolations())}
MD;
- $sniffDoc = preg_replace('/\n{3,}/', "\n\n",$sniffDoc);
- return preg_replace('/\n{2,}$/', "\n",$sniffDoc);
+ $sniffDoc = preg_replace('/\n{3,}/', "\n\n", $sniffDoc);
+ return preg_replace('/\n{2,}$/', "\n", $sniffDoc);
}
private function getDescription(Sniff $sniff): string
diff --git a/src/Handler/GenerateHandler.php b/src/Handler/GenerateHandler.php
index 8ebedf8..2aa7e83 100644
--- a/src/Handler/GenerateHandler.php
+++ b/src/Handler/GenerateHandler.php
@@ -3,7 +3,8 @@
namespace App\Handler;
-use App\CodeRepository\CodeRepository;
+use App\CodeRepository\CodeRepositoryFactory;
+use App\Configuration\ConfigurationRepository;
use App\Generator\Generator;
use App\SniffFinder\SniffFinder;
use App\Value\Folder;
@@ -11,15 +12,22 @@
class GenerateHandler
{
- private CodeRepository $codeRepository;
+ private CodeRepositoryFactory $codeRepositoryFactory;
private Generator $generator;
private SniffFinder $sniffFinder;
+ private ConfigurationRepository $configRepo;
- public function __construct(CodeRepository $codeRepository, Generator $generator, SniffFinder $sniffFinder)
+ public function __construct(
+ CodeRepositoryFactory $codeRepositoryFactory,
+ Generator $generator,
+ SniffFinder $sniffFinder,
+ ConfigurationRepository $configRepo
+ )
{
- $this->codeRepository = $codeRepository;
+ $this->codeRepositoryFactory = $codeRepositoryFactory;
$this->generator = $generator;
$this->sniffFinder = $sniffFinder;
+ $this->configRepo = $configRepo;
}
/**
@@ -27,27 +35,32 @@ public function __construct(CodeRepository $codeRepository, Generator $generator
*/
public function handle(string $sniffPath = null): iterable
{
- $repoName = 'PHPCompatibility/PHPCompatibility';
- $repoPath = $this->codeRepository->downloadCode($repoName);
+ $config = $this->configRepo->getConfig();
$filesystem = new Filesystem();
- $standardPath = new Folder($repoPath . 'PHPCompatibility/');
- yield "Searching for sniffs...";
+ foreach ($config->getSources() as $source) {
+ $codeRepository = $this->codeRepositoryFactory->fromType($source->getType());
+ $sourceFolder = $codeRepository->getFolder($source);
+ foreach ($source->getStandards() as $standard) {
+ $standardFolder = new Folder($sourceFolder . $standard->getPath() . '/');
+ yield "Searching for sniffs in {$standardFolder}...";
- if ($sniffPath !== null) {
- $sniffs = [$this->sniffFinder->getSniff($standardPath, $sniffPath)];
- } else {
- $sniffs = $this->sniffFinder->getSniffs($standardPath);
- }
+ if ($sniffPath !== null) {
+ $sniffs = [$this->sniffFinder->getSniff($standardFolder, $sourceFolder, $sniffPath)];
+ } else {
+ $sniffs = $this->sniffFinder->getSniffs($standardFolder, $sourceFolder);
+ }
- foreach ($sniffs as $sniff) {
- $markdownPath = $this->sniffCodeToMarkdownPath($sniff->getCode());
- $filesystem->dumpFile(
- // TODO: perhaps we can move this logic to the the sniff class
- $markdownPath,
- $this->generator->createSniffDoc($sniff)
- );
- yield "Created file: {$markdownPath}";
+ foreach ($sniffs as $sniff) {
+ $markdownPath = $this->sniffCodeToMarkdownPath($sniff->getCode());
+ $filesystem->dumpFile(
+ // TODO: perhaps we can move this logic to the the sniff class
+ $markdownPath,
+ $this->generator->createSniffDoc($sniff)
+ );
+ yield "Created file: {$markdownPath}";
+ }
+ }
}
}
diff --git a/src/Parser/SniffParser.php b/src/Parser/SniffParser.php
index d8e4565..11973b6 100644
--- a/src/Parser/SniffParser.php
+++ b/src/Parser/SniffParser.php
@@ -206,7 +206,8 @@ private function getUrls(ReflectionClass $classInfo, array $xmlUrls): UrlList
->getTagsByName('link');
$urls = array_map(function (string $url) {
- return new Url($url);
+ preg_match('/(http[^ ]+)/', $url, $matches);
+ return new Url($matches[0]);
}, $links);
return new UrlList(array_merge($urls, $xmlUrls));
diff --git a/src/SniffFinder/FilesystemSniffFinder.php b/src/SniffFinder/FilesystemSniffFinder.php
index 58f744f..ee4bddf 100644
--- a/src/SniffFinder/FilesystemSniffFinder.php
+++ b/src/SniffFinder/FilesystemSniffFinder.php
@@ -18,21 +18,18 @@
class FilesystemSniffFinder implements SniffFinder
{
- public function getSniff(Folder $folder, string $sniffPath): Sniff
+ public function getSniff(Folder $standardFolder, Folder $sourceFolder, string $sniffPath): Sniff
{
$parser = new SniffParser();
- $projectSourceLocator = $this->createProjectSourceLocator($folder);
+ $projectSourceLocator = $this->createProjectSourceLocator($sourceFolder);
return $parser->parse($sniffPath, $projectSourceLocator);
}
- public function getSniffs(Folder $folder): iterable
+ private function createProjectSourceLocator(Folder $folder): SourceLocator
{
- $parser = new SniffParser();
- $globSniffs = new GlobIterator($folder->getPath() . 'Sniffs/*/*Sniff.php');
- $projectSourceLocator = $this->createProjectSourceLocator($folder);
- foreach ($globSniffs as $fileInfo) {
- yield $parser->parse($fileInfo->getPathname(), $projectSourceLocator);
- }
+ $astLocator = (new BetterReflection())->astLocator();
+ $fileInfoIterator = $this->recursiveSearch($folder);
+ return new FileIteratorSourceLocator($fileInfoIterator, $astLocator);
}
/**
@@ -47,10 +44,13 @@ private function recursiveSearch(Folder $folder): Iterator
});
}
- private function createProjectSourceLocator(Folder $folder): SourceLocator
+ public function getSniffs(Folder $standardFolder, Folder $sourceFolder): iterable
{
- $astLocator = (new BetterReflection())->astLocator();
- $fileInfoIterator = $this->recursiveSearch($folder);
- return new FileIteratorSourceLocator($fileInfoIterator, $astLocator);
+ $parser = new SniffParser();
+ $globSniffs = new GlobIterator($standardFolder->getPath() . 'Sniffs/*/*Sniff.php');
+ $projectSourceLocator = $this->createProjectSourceLocator($sourceFolder);
+ foreach ($globSniffs as $fileInfo) {
+ yield $parser->parse($fileInfo->getPathname(), $projectSourceLocator);
+ }
}
}
diff --git a/src/SniffFinder/SniffFinder.php b/src/SniffFinder/SniffFinder.php
index c512125..e19088b 100644
--- a/src/SniffFinder/SniffFinder.php
+++ b/src/SniffFinder/SniffFinder.php
@@ -8,10 +8,10 @@
interface SniffFinder
{
- public function getSniff(Folder $folder, string $sniffPath): Sniff;
+ public function getSniff(Folder $standardFolder, Folder $sourceFolder, string $sniffPath): Sniff;
/**
* @return iterable
*/
- public function getSniffs(Folder $folder): iterable;
+ public function getSniffs(Folder $standardFolder, Folder $sourceFolder): iterable;
}
diff --git a/src/Value/Diff.php b/src/Value/Diff.php
index 03e1f53..b991ae9 100644
--- a/src/Value/Diff.php
+++ b/src/Value/Diff.php
@@ -5,7 +5,7 @@
use Assert\Assert;
-class Diff
+final class Diff
{
private string $before;
private string $after;
diff --git a/src/Value/Folder.php b/src/Value/Folder.php
index 76fdb84..e14fd2d 100644
--- a/src/Value/Folder.php
+++ b/src/Value/Folder.php
@@ -5,7 +5,7 @@
use Assert\Assert;
-class Folder
+final class Folder
{
private string $path;
@@ -17,7 +17,7 @@ public function __construct(string $path)
$this->path = $path;
}
- public function __toString()
+ public function __toString(): string
{
return $this->getPath();
}
diff --git a/src/Value/Property.php b/src/Value/Property.php
index 80856dc..1c017c4 100644
--- a/src/Value/Property.php
+++ b/src/Value/Property.php
@@ -5,7 +5,7 @@
use Assert\Assert;
-class Property
+final class Property
{
private string $name;
private string $type;
diff --git a/src/Value/Sniff.php b/src/Value/Sniff.php
index deb666d..c277762 100644
--- a/src/Value/Sniff.php
+++ b/src/Value/Sniff.php
@@ -5,7 +5,7 @@
use Assert\Assert;
-class Sniff
+final class Sniff
{
private string $code;
private string $docblock;
diff --git a/src/Value/Url.php b/src/Value/Url.php
index 92ed716..bbe8ebb 100644
--- a/src/Value/Url.php
+++ b/src/Value/Url.php
@@ -5,19 +5,19 @@
use Assert\Assert;
-class Url
+final class Url
{
private string $url;
public function __construct(string $url)
{
Assert::that($url)
- ->url();
+ ->url('Not a valid URL: ' . $url);
$this->url = $url;
}
- public function __toString()
+ public function __toString(): string
{
return $this->getUrl();
}
diff --git a/src/Value/UrlList.php b/src/Value/UrlList.php
index c852847..1fbd5e2 100644
--- a/src/Value/UrlList.php
+++ b/src/Value/UrlList.php
@@ -6,7 +6,7 @@
/**
* Collection of unique URLs.
*/
-class UrlList
+final class UrlList
{
/**
* @var Url[]
diff --git a/src/Value/Violation.php b/src/Value/Violation.php
index 91ca7e5..29e4912 100644
--- a/src/Value/Violation.php
+++ b/src/Value/Violation.php
@@ -5,7 +5,7 @@
use Assert\Assert;
-class Violation
+final class Violation
{
private string $code;
private string $description;
diff --git a/tests/CodeRepository/CodeRepositoryFactoryTest.php b/tests/CodeRepository/CodeRepositoryFactoryTest.php
new file mode 100644
index 0000000..932af42
--- /dev/null
+++ b/tests/CodeRepository/CodeRepositoryFactoryTest.php
@@ -0,0 +1,40 @@
+expectException(InvalidArgumentException::class);
+ (new CodeRepositoryFactory)->fromType('INVALID');
+ }
+
+ /** @test */
+ public function fromType_WithGit_ReturnGitImplementation()
+ {
+ self::assertInstanceOf(
+ GitCodeRepository::class,
+ (new CodeRepositoryFactory)->fromType(Source::TYPE_GIT)
+ );
+ }
+
+ /** @test */
+ public function fromType_WithLocal_ReturnLocalImplementation()
+ {
+ self::assertInstanceOf(
+ LocalCodeRepository::class,
+ (new CodeRepositoryFactory)->fromType(Source::TYPE_LOCAL)
+ );
+ }
+}
diff --git a/tests/CodeRepository/GitCodeRepositoryTest.php b/tests/CodeRepository/GitCodeRepositoryTest.php
new file mode 100644
index 0000000..4798400
--- /dev/null
+++ b/tests/CodeRepository/GitCodeRepositoryTest.php
@@ -0,0 +1,62 @@
+expectException(RuntimeException::class);
+ $sourcePath = 'var/repos/MISSING.git';
+ $this->codeRepo->getFolder(new Source($sourcePath, []));
+ }
+
+ /** @test */
+ public function getFolder_WithGitPath_InstallComposer()
+ {
+ $this->createGitRepo();
+ (new Filesystem())->remove('var/repos/Standard'); // force fresh clone
+
+ $this->codeRepo->getFolder(new Source(self::LOCAL_GIT_PATH, []));
+ self::assertFileExists('var/repos/Standard/composer.lock');
+ }
+
+ private function createGitRepo(): void
+ {
+ $fs = new Filesystem;
+ $gitPath = self::LOCAL_GIT_PATH;
+ $fs->mkdir($gitPath);
+ $fs->dumpFile($gitPath . '/composer.json', '{}');
+ if (getenv('IS_CI_TEST')) {
+ `git config --global user.email "you@example.com"`;
+ `git config --global user.name "Your Name"`;
+ }
+ `cd {$gitPath} && git init && git add composer.json && git commit -m "Init"`;
+ }
+
+ /** @test */
+ public function getFolder_WithExistingGitClone_InstallComposer()
+ {
+ $this->createGitRepo();
+
+ $this->codeRepo->getFolder(new Source(self::LOCAL_GIT_PATH, []));
+ self::assertFileExists('var/repos/Standard/composer.lock');
+ }
+
+ protected function setUp(): void
+ {
+ $this->codeRepo = new GitCodeRepository();
+ }
+}
diff --git a/tests/CodeRepository/LocalCodeRepositoryTest.php b/tests/CodeRepository/LocalCodeRepositoryTest.php
new file mode 100644
index 0000000..6071176
--- /dev/null
+++ b/tests/CodeRepository/LocalCodeRepositoryTest.php
@@ -0,0 +1,43 @@
+expectException(RuntimeException::class);
+ $sourcePath = 'var/repos/MISSING';
+ $this->codeRepo->getFolder(new Source($sourcePath, []));
+ }
+
+ /** @test */
+ public function getFolder_WithExistingPath_InstallComposer()
+ {
+ $fs = new Filesystem;
+ $sourcePath = self::LOCAL_PATH;
+ $fs->remove($sourcePath);
+ $fs->mkdir($sourcePath);
+ $fs->dumpFile($sourcePath . '/composer.json', '{}');
+
+ $this->codeRepo->getFolder(new Source($sourcePath, []));
+ self::assertFileExists('var/repos/Standard/composer.lock');
+ }
+
+ protected function setUp(): void
+ {
+ $this->codeRepo = new LocalCodeRepository();
+ }
+}
diff --git a/tests/Configuration/Value/ConfigurationTest.php b/tests/Configuration/Value/ConfigurationTest.php
new file mode 100644
index 0000000..bb8b7b1
--- /dev/null
+++ b/tests/Configuration/Value/ConfigurationTest.php
@@ -0,0 +1,51 @@
+createValidVO()->getSources(),
+ );
+ }
+
+ private function createValidVO(): Configuration
+ {
+ return new Configuration(
+ self::FORMAT,
+ self::$SOURCES
+ );
+ }
+
+ /** @test */
+ public function getFormat()
+ {
+ self::assertEquals(
+ self::FORMAT,
+ $this->createValidVO()->getFormat(),
+ );
+ }
+}
diff --git a/tests/Configuration/Value/SourceTest.php b/tests/Configuration/Value/SourceTest.php
new file mode 100644
index 0000000..e35bd13
--- /dev/null
+++ b/tests/Configuration/Value/SourceTest.php
@@ -0,0 +1,56 @@
+getStandards()
+ );
+ }
+
+ /** @test */
+ public function getLocalFolder_WithGit_PrependDownloadPath()
+ {
+ self::assertEquals(
+ new Folder('var/repos/repo/'),
+ (new Source('path/to/repo.git', []))->getLocalFolder()
+ );
+ }
+
+ /** @test */
+ public function getType_WithGit_ReturnGit()
+ {
+ self::assertEquals(
+ Source::TYPE_GIT,
+ (new Source('path/to/repo.git', []))->getType()
+ );
+ }
+
+ /** @test */
+ public function getPath()
+ {
+ self::assertEquals(
+ self::SOURCE_PATH,
+ (new Source(self::SOURCE_PATH, []))->getPath()
+ );
+ }
+}
diff --git a/tests/Configuration/Value/StandardTest.php b/tests/Configuration/Value/StandardTest.php
new file mode 100644
index 0000000..23e3bb9
--- /dev/null
+++ b/tests/Configuration/Value/StandardTest.php
@@ -0,0 +1,30 @@
+expectException(InvalidArgumentException::class);
+ new Standard('');
+ }
+
+ /** @test */
+ public function getPath()
+ {
+ self::assertEquals(
+ self::STANDARD_PATH,
+ (new Standard(self::STANDARD_PATH))->getPath()
+ );
+ }
+}
diff --git a/tests/Configuration/XmlConfigurationRepositoryTest.php b/tests/Configuration/XmlConfigurationRepositoryTest.php
new file mode 100644
index 0000000..a452182
--- /dev/null
+++ b/tests/Configuration/XmlConfigurationRepositoryTest.php
@@ -0,0 +1,106 @@
+expectException(RuntimeException::class);
+ $this->repo->getConfig();
+ }
+
+ /** @test */
+ public function getConfig_WithInvalidSchema_ThrowException()
+ {
+ $this->expectException(RuntimeException::class);
+
+ $xmlContent =
+ '
+
+ ';
+
+ (new Filesystem)->dumpFile(self::XML_FILE_PATH, $xmlContent);
+
+ $this->repo->getConfig();
+ }
+
+ /** @test */
+ public function getConfig_WithBothFiles_PickNonDist()
+ {
+ $xmlContent =
+ '
+
+
+
+
+ ';
+
+ (new Filesystem)->dumpFile(self::XML_FILE_PATH, $xmlContent);
+
+ $xmlDistContent =
+ '
+
+
+
+ ';
+
+ (new Filesystem)->dumpFile(self::XML_DIST_FILE_PATH, $xmlDistContent);
+
+ $config = $this->repo->getConfig();
+ self::assertEquals(
+ 'Xml',
+ $config->getSources()[0]->getStandards()[0]->getPath()
+ );
+ }
+
+ /** @test */
+ public function getConfig_WithValidFile_ReturnConfiguration()
+ {
+ $xmlContent =
+ '
+
+
+
+
+ ';
+
+ (new Filesystem)->dumpFile(self::XML_FILE_PATH, $xmlContent);
+
+ self::assertEquals(
+ new Configuration(
+ 'markdown',
+ [
+ new Source('path/to/code', [
+ new Standard('Standard')
+ ]),
+ ]
+ ),
+ $this->repo->getConfig()
+ );
+ }
+
+ protected function setUp(): void
+ {
+ $fs = new Filesystem;
+ $fs->remove(self::XML_DIST_FILE_PATH);
+ $fs->remove(self::XML_FILE_PATH);
+ $this->repo = new XmlConfigurationRepository(new Folder('var/tests/'));
+ }
+}
diff --git a/tests/Handler/GenerateHandlerTest.php b/tests/Handler/GenerateHandlerTest.php
index eb92c2a..9f46cb8 100644
--- a/tests/Handler/GenerateHandlerTest.php
+++ b/tests/Handler/GenerateHandlerTest.php
@@ -4,6 +4,11 @@
namespace App\Tests\Handler;
use App\CodeRepository\CodeRepository;
+use App\CodeRepository\CodeRepositoryFactory;
+use App\Configuration\ConfigurationRepository;
+use App\Configuration\Value\Configuration;
+use App\Configuration\Value\Source;
+use App\Configuration\Value\Standard;
use App\Generator\Generator;
use App\Handler\GenerateHandler;
use App\SniffFinder\SniffFinder;
@@ -23,9 +28,9 @@ class GenerateHandlerTest extends TestCase
*/
private GenerateHandler $handler;
/**
- * @var CodeRepository|MockObject
+ * @var CodeRepositoryFactory|MockObject
*/
- private $codeRepository;
+ private $codeRepositoryFactory;
/**
* @var Generator|MockObject
*/
@@ -34,11 +39,18 @@ class GenerateHandlerTest extends TestCase
* @var SniffFinder|MockObject
*/
private $sniffFinder;
+ /**
+ * @var ConfigurationRepository|MockObject
+ */
+ private $configRepo;
/** @test */
public function handle_WithoutArguments_CreatesFile()
{
- $this->codeRepository->method('downloadCode')->willReturn(new Folder('var/tests/'));
+ $codeRepository = $this->createMock(CodeRepository::class);
+ $codeRepository->method('getFolder')->willReturn(new Folder('var/tests/'));
+ $this->codeRepositoryFactory->method('fromType')->willReturn($codeRepository);
+
$sniffs = $this->createSniffs(['First', 'Second']);
$this->sniffFinder->method('getSniffs')->willReturn($sniffs);
$this->generator->method('createSniffDoc')->withConsecutive([$sniffs[0]], [$sniffs[1]]);
@@ -48,7 +60,7 @@ public function handle_WithoutArguments_CreatesFile()
self::assertEquals(
[
- 'Searching for sniffs...',
+ 'Searching for sniffs in var/tests/Standard/...',
'Created file: var/markdown/Standard/Category/First.md',
'Created file: var/markdown/Standard/Category/Second.md'
],
@@ -89,7 +101,9 @@ private function createSniff(string $name): Sniff
/** @test */
public function handle_WithSniffPath_CreatesSingleFile()
{
- $this->codeRepository->method('downloadCode')->willReturn(new Folder('var/tests/'));
+ $codeRepository = $this->createMock(CodeRepository::class);
+ $codeRepository->method('getFolder')->willReturn(new Folder('var/tests/'));
+ $this->codeRepositoryFactory->method('fromType')->willReturn($codeRepository);
$this->sniffFinder->method('getSniff')->willReturn($this->createSniff('First'));
/** @var \Generator $messages */
@@ -97,7 +111,7 @@ public function handle_WithSniffPath_CreatesSingleFile()
self::assertEquals(
[
- 'Searching for sniffs...',
+ 'Searching for sniffs in var/tests/Standard/...',
'Created file: var/markdown/Standard/Category/First.md',
],
iterator_to_array($messages)
@@ -108,14 +122,25 @@ protected function setUp(): void
{
(new Filesystem())->remove('var/markdown/Standard');
- $this->codeRepository = $this->createMock(CodeRepository::class);
+ $this->codeRepositoryFactory = $this->createMock(CodeRepositoryFactory::class);
$this->generator = $this->createMock(Generator::class);
$this->sniffFinder = $this->createMock(SniffFinder::class);
+ $this->configRepo = $this->createMock(ConfigurationRepository::class);
+
+ $this->configRepo->method('getConfig')->willReturn(new Configuration(
+ 'markdown',
+ [
+ new Source('../Standard', [
+ new Standard('Standard')
+ ])
+ ]
+ ));
$this->handler = new GenerateHandler(
- $this->codeRepository,
+ $this->codeRepositoryFactory,
$this->generator,
- $this->sniffFinder
+ $this->sniffFinder,
+ $this->configRepo
);
}
}
diff --git a/tests/SniffFinder/FilesystemSniffFinderTest.php b/tests/SniffFinder/FilesystemSniffFinderTest.php
index e161aff..457f88d 100644
--- a/tests/SniffFinder/FilesystemSniffFinderTest.php
+++ b/tests/SniffFinder/FilesystemSniffFinderTest.php
@@ -32,6 +32,9 @@ public function getSniffs()
$sniffs = $this->finder->getSniffs(
new Folder(
'var/tests/src/Standard/'
+ ),
+ new Folder(
+ 'var/tests/'
)
);
self::assertEquals(
@@ -114,6 +117,9 @@ public function getSniff()
new Folder(
'var/tests/src/Standard/'
),
+ new Folder(
+ 'var/tests/'
+ ),
self::PHP_SNIFF_PATH
)
);
diff --git a/var/repos/.gitkeep b/var/repos/.gitkeep
deleted file mode 100644
index e69de29..0000000