diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0c4bb32..05c3589 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -13,16 +13,16 @@ jobs:
- name: "Install PHP with extensions"
uses: "shivammathur/setup-php@v2"
with:
- php-version: "7.2"
+ php-version: "7.4"
extensions: imagick
ini-values: memory_limit=-1
coverage: xdebug
- tools: composer:v1
+ tools: composer
- name: "Install dependencies with composer"
run: |
sudo apt-get install graphviz
- composer install --no-interaction --no-progress --no-suggest
+ composer install --no-interaction --no-progress
- name: "Code quality checks"
run: "make check"
diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
index 6e7efc9..6aecae5 100644
--- a/.github/workflows/pages.yml
+++ b/.github/workflows/pages.yml
@@ -15,9 +15,9 @@ jobs:
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
- php-version: "7.1"
+ php-version: "7.4"
ini-values: memory_limit=-1
- tools: composer:v1
+ tools: composer
- name: "Generate documentation"
run: |
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index c0bd1bb..e2236eb 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -17,7 +17,7 @@ jobs:
- name: "Install PHP with extensions"
uses: "shivammathur/setup-php@v2"
with:
- php-version: "7.2"
+ php-version: "7.4"
extensions: imagick
ini-values: memory_limit=-1, phar.readonly=Off
tools: composer:v1
@@ -25,11 +25,12 @@ jobs:
- name: "Install dependencies with composer"
run: |
sudo apt-get install graphviz
- composer install --optimize-autoloader --prefer-dist --no-interaction --no-progress --no-suggest --no-dev
+ composer install --optimize-autoloader --prefer-dist --no-interaction --no-progress --no-suggest --no-dev --no-plugins
- name: "Build PHAR file"
run: |
wget https://github.com/box-project/box/releases/download/3.13.0/box.phar
+ chmod +x box.phar
./box.phar compile -vv
gpg -u montealegreluis@gmail.com --detach-sign --output phuml.phar.asc phuml.phar
diff --git a/.gitignore b/.gitignore
index 11c619f..06d3221 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,4 @@ box.phar
phuml.phar
phuml.phar.pubkey
phuml.phar.version
+infection.log
diff --git a/.php-cs-fixer-tests.php b/.php-cs-fixer-tests.php
index f5db509..9b88634 100644
--- a/.php-cs-fixer-tests.php
+++ b/.php-cs-fixer-tests.php
@@ -38,7 +38,7 @@
'blank_line_after_opening_tag' => false,
'declare_strict_types' => true,
'header_comment' => [
- 'header' => 'PHP version 7.2
+ 'header' => 'PHP version 7.4
This source file is subject to the license that is bundled with this package in the file LICENSE.',
'comment_type' => 'PHPDoc',
diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php
index d26c1e9..5368447 100644
--- a/.php-cs-fixer.php
+++ b/.php-cs-fixer.php
@@ -36,7 +36,7 @@
'blank_line_after_opening_tag' => false,
'declare_strict_types' => true,
'header_comment' => [
- 'header' => 'PHP version 7.2
+ 'header' => 'PHP version 7.4
This source file is subject to the license that is bundled with this package in the file LICENSE.',
'comment_type' => 'PHPDoc',
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 00cc8f8..dd9e279 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -14,6 +14,23 @@ By participating in this project you agree to abide by its terms.
Pull requests for bug fixes must be based on the current stable branch whereas pull requests for new features must be based on the `master` branch.
+### Git commit format
+
+Commit messages must follow the [Conventional Commits Specification](https://www.conventionalcommits.org/en/v1.0.0-beta.2/) which is enforced as a Git pre-commit hook via [GrumPHP](https://github.com/phpro/grumphp).
+
+The allowed commit types are:
+
+- `build` for changes to Github Actions or Scrutinizer (CI Pipeline)
+- `chore` for changes to the configuration any of the code quality tools used by this project (PHPUnit, PHP CS Fixer, Rector, Composer Normalize, Composer Require Checker, etc.)
+- `docs` for updates or additions to the documentation
+- `feat` for new features
+- `fix` for a fix to an existing console command
+- `refactor` for refactoring changes
+- `style` for changes that only format code
+- `test` for tests only changes
+
+It is recommended to follow the [7 rules of a good commit message](https://chris.beams.io/posts/git-commit/#seven-rules).
+
## Coding Guidelines
This project follows the coding standards proposed in [PSR-2][psr2]
@@ -24,7 +41,7 @@ Run the following command if you modified either production code or tests.
make format
```
-[Make][make] will run [PHP CS fixer][cs-fixer] in both folders `src` and `tests`.
+[Make][make] will run [PHP CS fixer][cs-fixer] and [Rector](https://getrector.org/) in both folders `src` and `tests`.
## Using phUML from a Git checkout
diff --git a/Makefile b/Makefile
index 702365a..52b629e 100644
--- a/Makefile
+++ b/Makefile
@@ -8,8 +8,10 @@ test:
@docker-compose run --rm tests php vendor/bin/phpunit --testdox
coverage:
- @docker-compose run --rm tests php vendor/bin/phpunit --coverage-html build/coverage
+ @docker-compose run --rm -e XDEBUG_MODE=coverage tests php vendor/bin/phpunit --coverage-html build/coverage
+infection:
+ @docker-compose run --rm -e XDEBUG_MODE=coverage tests php vendor/bin/infection --threads=4
diagram:
@docker-compose run --rm tests php bin/phuml phuml:diagram $(ARGS)
@@ -26,8 +28,8 @@ format:
@vendor/bin/php-cs-fixer fix --config=.php-cs-fixer-tests.php -v --using-cache no
check:
- @vendor/bin/grumphp run
+ @vendor/bin/grumphp run --no-interaction
@vendor/bin/composer-require-checker check
@docker-compose run --rm tests vendor/bin/phpunit --testsuite 'Integration tests'
- @vendor/bin/php-cs-fixer fix --config=.php-cs-fixer-tests.php -v --dry-run --using-cache=no
@vendor/bin/rector process --dry-run
+ @docker-compose run --rm -e XDEBUG_MODE=coverage tests php vendor/bin/infection --threads=4
diff --git a/README.md b/README.md
index 832dd5c..76339c6 100644
--- a/README.md
+++ b/README.md
@@ -3,6 +3,7 @@
[![CI workflow](https://github.com/montealegreluis/phuml/actions/workflows/ci.yml/badge.svg)](https://github.com/montealegreluis/phuml/actions/workflows/ci.yml)
[![Scrutinizer Code Quality][scrutinizer-badge]][scrutinizer]
[![Code Coverage][coverage-badge]][coverage]
+[![Infection MSI](https://badge.stryker-mutator.io/github.com/montealegreluis/phuml/master)](https://infection.github.io)
[![Latest Stable Version][stable-badge]][packagist]
[![Minimum PHP Version][php-version-badge]][php]
@@ -68,7 +69,7 @@ Special thanks to all of these [awesome contributors][contributors].
[codebase]: https://github.com/jakobwesthoff/phuml/tree/master/src
[stable-badge]: https://img.shields.io/packagist/v/phuml/phuml.svg?style=flat-square
[packagist]: https://packagist.org/packages/phuml/phuml
-[php-version-badge]: https://img.shields.io/badge/php-%3E%3D%207.1-8892BF.svg?style=flat-square
+[php-version-badge]: https://img.shields.io/badge/php-%3E%3D%207.4-8892BF.svg?style=flat-square
[php]: https://php.net/
[luis]: https://github.com/MontealegreLuis
[jakob]: https://github.com/jakobwesthoff
diff --git a/composer.json b/composer.json
index 92003d5..893d6fc 100644
--- a/composer.json
+++ b/composer.json
@@ -15,40 +15,42 @@
}
],
"require": {
- "php": "^7.2",
+ "php": "^7.4",
"ext-tokenizer": "*",
- "nikic/php-parser": "^4.10.5",
- "symfony/console": "^5.3.0",
- "symfony/filesystem": "^5.3.0",
+ "nikic/php-parser": "^4.11.0",
+ "symfony/console": "^5.3.2",
+ "symfony/filesystem": "^5.3.3",
"symfony/finder": "^5.3.0",
- "symfony/process": "^5.3.0",
+ "symfony/process": "^5.3.2",
"twig/twig": "^3.3.2",
"webmozart/assert": "^1.10.0"
},
"require-dev": {
"ext-imagick": "*",
- "ergebnis/composer-normalize": "^2.14.0",
+ "ergebnis/composer-normalize": "^2.15.0",
"friendsofphp/php-cs-fixer": "^3.0.0",
+ "infection/infection": "^0.23.0",
"lupka/phpunit-compare-images": "^1.0.0",
- "maglnet/composer-require-checker": "^2.1.0",
- "phpro/grumphp": "^0.19.1",
+ "maglnet/composer-require-checker": "^3.3.0",
+ "phpro/grumphp": "^1.3.3",
+ "phpspec/prophecy-phpunit": "^2.0.1",
"phpstan/extension-installer": "^1.1.0",
- "phpstan/phpstan": "^0.12.88",
- "phpstan/phpstan-strict-rules": "^0.12.9",
- "phpunit/phpunit": "^8.5.15",
+ "phpstan/phpstan": "^0.12.90",
+ "phpstan/phpstan-strict-rules": "^0.12.10",
+ "phpunit/phpunit": "^9.5.6",
"pyrech/composer-changelogs": "^1.7.1",
- "rector/rector": "^0.11.8"
+ "rector/rector": "0.11.32"
},
"config": {
"optimize-autoloader": true,
"platform": {
- "php": "7.2.34"
+ "php": "7.4.20"
},
"sort-packages": true
},
"extra": {
"branch-alias": {
- "dev-master": "4.0-dev"
+ "dev-master": "5.0-dev"
}
},
"autoload": {
diff --git a/containers/tests/Dockerfile b/containers/tests/Dockerfile
index bc7d3b6..b08d048 100644
--- a/containers/tests/Dockerfile
+++ b/containers/tests/Dockerfile
@@ -1,8 +1,10 @@
-FROM php:7.2.34-cli-alpine3.12
+FROM php:7.4.20-cli-alpine3.12
RUN apk add --update --no-cache autoconf g++ pkgconfig imagemagick imagemagick-dev make ttf-freefont graphviz \
&& printf "\n" | pecl install imagick \
- && echo "extension=imagick.so" >> /usr/local/etc/php/php.ini
+ && echo "extension=imagick.so" >> /usr/local/etc/php/php.ini \
+ && printf "\n" | pecl install xdebug \
+ && echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" > /usr/local/etc/php/conf.d/xdebug.ini
RUN mkdir -p /usr/src/phuml
diff --git a/docs/installation.md b/docs/installation.md
index f95b1ab..c70de2f 100644
--- a/docs/installation.md
+++ b/docs/installation.md
@@ -16,4 +16,6 @@ Alternatively, you may use [Composer](https://getcomposer.org/) to download and
```bash
composer require phuml/phuml
+# or globally
+composer global require phuml/phuml
```
diff --git a/docs/types.md b/docs/types.md
index 24f7d09..53a8207 100644
--- a/docs/types.md
+++ b/docs/types.md
@@ -12,8 +12,8 @@ The class below will show type information for all of its attributes and methods
classes = $classes;
+ }
+
+ /** @return ClassDefinition[] */
+ public function classes(): array
+ {
+ return $this->classes;
+ }
+}
+```
+
+In the 3 cases above, phUML will use `ClassDefinition[]` instead of `array`.
diff --git a/grumphp.yml b/grumphp.yml
index 43fcc44..5995dba 100644
--- a/grumphp.yml
+++ b/grumphp.yml
@@ -12,6 +12,16 @@ grumphp:
max_subject_width: 50
case_insensitive: true
multiline: true
+ type_scope_conventions:
+ - types:
+ - build
+ - chore
+ - docs
+ - feat
+ - fix
+ - refactor
+ - style
+ - test
composer:
composer_normalize:
phpstan:
@@ -26,3 +36,7 @@ grumphp:
config_contains_finder: true
config: .php-cs-fixer.php
triggered_by: ['php']
+ phpcsfixer2_test:
+ config: .php-cs-fixer-tests.php
+ metadata:
+ task: phpcsfixer2
diff --git a/index.md b/index.md
index a900b2d..f759457 100644
--- a/index.md
+++ b/index.md
@@ -3,11 +3,12 @@
![CI workflow](https://github.com/montealegreluis/phuml/actions/workflows/ci.yml/badge.svg)
[![Scrutinizer Code Quality][scrutinizer-badge]][scrutinizer]
[![Code Coverage][coverage-badge]][coverage]
+[![Infection MSI](https://badge.stryker-mutator.io/github.com/montealegreluis/phuml/master)](https://infection.github.io)
[![Latest Stable Version][stable-badge]][packagist]
[![Minimum PHP Version][php-badge]][php]
phUML is a fully automatic [UML][uml] class diagram generator written [PHP][php].
-It creates a class diagram from an OO codebase based on the UML specification.
+It creates a class diagram from an Object-Oriented codebase based on the UML specification.
To successfully create UML diagrams with phUML you will need to install the [graphviz][graphviz] toolkit.
@@ -32,5 +33,5 @@ You can take a look at the complete image by clicking [here][diagram].
[coverage]: https://scrutinizer-ci.com/g/MontealegreLuis/phuml/?branch=master
[stable-badge]: https://img.shields.io/packagist/v/phuml/phuml.svg?style=flat-square
[packagist]: https://packagist.org/packages/phuml/phuml
-[php-badge]: https://img.shields.io/badge/php-%3E%3D%207.1-8892BF.svg?style=flat-square
+[php-badge]: https://img.shields.io/badge/php-%3E%3D%207.4-8892BF.svg?style=flat-square
[php]: https://php.net/
diff --git a/infection.json.dist b/infection.json.dist
new file mode 100644
index 0000000..8d1412a
--- /dev/null
+++ b/infection.json.dist
@@ -0,0 +1,21 @@
+{
+ "source": {
+ "directories": [
+ "src"
+ ],
+ "excludes": [
+ "resources"
+ ]
+ },
+ "logs": {
+ "text": "infection.log",
+ "badge": {
+ "branch": "master"
+ }
+ },
+ "mutators": {
+ "@default": true
+ },
+ "minMsi": 85,
+ "minCoveredMsi": 85
+}
diff --git a/phar.sh b/phar.sh
deleted file mode 100755
index b302a16..0000000
--- a/phar.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/bash
-
-# Unpack secrets; -C ensures they unpack *in* the .travis directory
-tar xvf .travis/secrets.tar -C .
-
-# Setup SSH agent:
-eval "$(ssh-agent -s)" #start the ssh agent
-chmod 600 .travis/build.pem
-ssh-add .travis/build.pem
-
-# Setup git defaults:
-git config --global user.email "montealegreluis@gmail.com"
-git config --global user.name "phUML PHAR file deployment"
-
-# Add SSH-based remote to GitHub repo:
-git remote add deploy git@github.com:MontealegreLuis/phuml.git
-git fetch deploy
-
-# Get box and build PHAR
-curl -LSs https://box-project.github.io/box2/installer.php | php
-./box.phar build -vv
-
-# Without the following step, we cannot checkout the gh-pages branch due to
-# file conflicts:
-mv phuml.phar phuml.phar.tmp
-
-# Checkout gh-pages and add PHAR file and version:
-git checkout -b gh-pages deploy/gh-pages
-mv phuml.phar.tmp phuml.phar
-sha1sum phuml.phar > phuml.phar.version
-git add phuml.phar phuml.phar.version
-
-# Commit and push:
-git commit -m 'Update phUML phar file with latest version'
-git push deploy gh-pages:gh-pages
diff --git a/phpstan.neon b/phpstan.neon
index 80eba99..b66cbba 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -5,4 +5,3 @@ parameters:
inferPrivatePropertyTypeFromConstructor: true
ignoreErrors:
- "#Strict comparison using === between '@package_version@' and '@package_version@' will always evaluate to true#"
- - "#Unsafe usage of new static#"
diff --git a/phpunit.xml b/phpunit.xml
index 4690472..fcf057e 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -1,5 +1,6 @@
-
-
- tests/unit
-
-
- tests/integration
-
-
-
-
- src/
-
-
+ xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
+
+
+ src/
+
+
+
+
+ tests/unit
+
+
+ tests/integration
+
+
diff --git a/rector.php b/rector.php
index 376da9a..b5ddb9c 100644
--- a/rector.php
+++ b/rector.php
@@ -21,11 +21,11 @@
// Define what rule sets will be applied
$containerConfigurator->import(SetList::DEAD_CODE);
$containerConfigurator->import(SetList::CODE_QUALITY);
- $containerConfigurator->import(SetList::PHP_72);
+ $containerConfigurator->import(SetList::PHP_74);
- $parameters->set(Option::PHP_VERSION_FEATURES, PhpVersion::PHP_72);
+ $parameters->set(Option::PHP_VERSION_FEATURES, PhpVersion::PHP_74);
- // Path to phpstan with extensions, that PHPStan in Rector uses to determine types
+ // Path to PHPStan with extensions, that PHPStan in Rector uses to determine types
$parameters->set(Option::PHPSTAN_FOR_RECTOR_PATH, getcwd() . '/phpstan.neon');
$services = $containerConfigurator->services();
diff --git a/src/Code/Attributes/Attribute.php b/src/Code/Attributes/Attribute.php
index c74d5f0..cff192a 100644
--- a/src/Code/Attributes/Attribute.php
+++ b/src/Code/Attributes/Attribute.php
@@ -1,6 +1,6 @@
extractType($comment);
+ }
+
+ public function attributeType(): TypeDeclaration
+ {
+ return $this->attributeType;
+ }
+
+ public function hasAttributeType(): bool
{
- return new AttributeDocBlock($text);
+ return $this->attributeType->isPresent();
}
- public function extractType(): TypeDeclaration
+ private function extractType(?string $comment): void
{
- $type = null;
- if (preg_match(self::$varExpression, (string) $this->comment, $matches) === 1) {
- $type = trim($matches[1]);
+ if (preg_match(self::VAR_EXPRESSION, (string) $comment, $matches) === 1) {
+ $this->attributeType = TypeDeclaration::from(trim($matches[1]));
+ return;
}
- return TypeDeclaration::from($type);
+ $this->attributeType = TypeDeclaration::absent();
}
}
diff --git a/src/Code/Attributes/Constant.php b/src/Code/Attributes/Constant.php
index 71a0948..60d0e21 100644
--- a/src/Code/Attributes/Constant.php
+++ b/src/Code/Attributes/Constant.php
@@ -1,6 +1,6 @@
methods, static function (Method $method): bool {
- return $method->isConstructor();
- });
+ $constructors = array_filter($this->methods, static fn (Method $method): bool => $method->isConstructor());
$constructor = reset($constructors);
return $constructor === false ? [] : $constructor->parameters();
@@ -81,9 +79,10 @@ public function constructorParameters(): array
*/
public function countAttributesByVisibility(Visibility $modifier): int
{
- return \count(array_filter($this->attributes, static function (Attribute $attribute) use ($modifier): bool {
- return $attribute->hasVisibility($modifier);
- }));
+ return \count(array_filter(
+ $this->attributes,
+ static fn (Attribute $attribute): bool => $attribute->hasVisibility($modifier)
+ ));
}
/**
@@ -93,9 +92,11 @@ public function countAttributesByVisibility(Visibility $modifier): int
*/
public function countTypedAttributesByVisibility(Visibility $modifier): int
{
- return \count(array_filter($this->attributes, static function (Attribute $attribute) use ($modifier): bool {
- return $attribute->hasTypeDeclaration() && $attribute->hasVisibility($modifier);
- }));
+ return \count(array_filter(
+ $this->attributes,
+ static fn (Attribute $attribute): bool =>
+ $attribute->hasTypeDeclaration() && $attribute->hasVisibility($modifier)
+ ));
}
/**
@@ -151,8 +152,6 @@ public function hasAttributes(): bool
*/
public function isAbstract(): bool
{
- return \count(array_filter($this->methods(), static function (Method $method): bool {
- return $method->isAbstract();
- })) > 0;
+ return \count(array_filter($this->methods(), static fn (Method $method): bool => $method->isAbstract())) > 0;
}
}
diff --git a/src/Code/Codebase.php b/src/Code/Codebase.php
index 2804785..96d6f6f 100644
--- a/src/Code/Codebase.php
+++ b/src/Code/Codebase.php
@@ -1,6 +1,6 @@
methods, static function (Method $method) use ($modifier): bool {
- return $method->hasVisibility($modifier);
- }));
+ return \count(array_filter(
+ $this->methods,
+ static fn (Method $method): bool => $method->hasVisibility($modifier)
+ ));
}
/**
diff --git a/src/Code/DocBlock.php b/src/Code/DocBlock.php
deleted file mode 100644
index 7ea6637..0000000
--- a/src/Code/DocBlock.php
+++ /dev/null
@@ -1,22 +0,0 @@
-comment = $comment;
- }
-}
diff --git a/src/Code/InterfaceDefinition.php b/src/Code/InterfaceDefinition.php
index 578d7f7..e74bcb3 100644
--- a/src/Code/InterfaceDefinition.php
+++ b/src/Code/InterfaceDefinition.php
@@ -1,14 +1,16 @@
extractParametersTypes($comment);
+ $this->extractReturnType($comment);
+ }
- public static function from(?string $comment): MethodDocBlock
+ public function hasReturnType(): bool
{
- return new MethodDocBlock($comment);
+ return $this->returnType->isPresent();
}
public function returnType(): TypeDeclaration
{
- $type = null;
- if (preg_match(self::$returnExpression, (string) $this->comment, $matches) === 1) {
- $type = trim($matches[1]);
- }
- return TypeDeclaration::from($type);
+ return $this->returnType;
+ }
+
+ public function hasTypeOfParameter(string $parameterName): bool
+ {
+ return isset($this->parametersTypes[$parameterName]);
}
public function typeOfParameter(string $parameterName): TypeDeclaration
{
- return $this->parameters[$parameterName] ?? TypeDeclaration::absent();
+ return $this->parametersTypes[$parameterName] ?? TypeDeclaration::absent();
}
- protected function __construct(?string $comment)
+ private function extractReturnType(?string $comment): void
{
- parent::__construct($comment);
- $this->setParameters();
+ if (preg_match(self::RETURN_EXPRESSION, (string) $comment, $matches) === 1) {
+ $this->returnType = TypeDeclaration::from(trim($matches[1]));
+ return;
+ }
+
+ $this->returnType = TypeDeclaration::absent();
}
- private function setParameters(): void
+ private function extractParametersTypes(?string $comment): void
{
- if (preg_match_all(self::$parameterExpression, (string) $this->comment, $matches) < 1) {
+ if (preg_match_all(self::PARAMETER_EXPRESSION, (string) $comment, $matches) < 1) {
+ $this->parametersTypes = [];
return;
}
foreach ($matches[0] as $typeHint) {
@@ -61,9 +72,9 @@ private function setParameters(): void
private function extractDeclarationFrom(string $typeHint): void
{
- if (preg_match(self::$parameterExpression, $typeHint, $match) === 1) {
+ if (preg_match(self::PARAMETER_EXPRESSION, $typeHint, $match) === 1) {
[$_, $type, $parameterName] = $match;
- $this->parameters[$parameterName] = TypeDeclaration::from($type);
+ $this->parametersTypes[$parameterName] = TypeDeclaration::from($type);
}
}
}
diff --git a/src/Code/Modifiers/CanBeAbstract.php b/src/Code/Modifiers/CanBeAbstract.php
index 2d43257..12ac024 100644
--- a/src/Code/Modifiers/CanBeAbstract.php
+++ b/src/Code/Modifiers/CanBeAbstract.php
@@ -1,6 +1,6 @@
'-',
'public' => '+',
'protected' => '#',
];
- /** @var string */
- private $modifier;
+ private string $modifier;
public function __construct(string $modifier)
{
diff --git a/src/Code/Modifiers/WithAbstractModifier.php b/src/Code/Modifiers/WithAbstractModifier.php
index d708044..7e9e932 100644
--- a/src/Code/Modifiers/WithAbstractModifier.php
+++ b/src/Code/Modifiers/WithAbstractModifier.php
@@ -1,6 +1,6 @@
name = $name;
}
public function __toString()
{
return $this->name;
}
-
- private function __construct(string $name)
- {
- $this->name = $name;
- }
}
diff --git a/src/Code/Named.php b/src/Code/Named.php
index 580ae01..1f302af 100644
--- a/src/Code/Named.php
+++ b/src/Code/Named.php
@@ -1,6 +1,6 @@
isPresent() && \in_array($type, self::$builtInTypes, true);
}
+ public function isBuiltInArray(): bool
+ {
+ return (string) $this->name === 'array';
+ }
+
public function isArray(): bool
{
return strpos((string) $this->name, '[]') === \strlen((string) $this->name) - 2;
@@ -87,7 +91,7 @@ public function __toString()
private function __construct(?string $name, bool $isNullable = false)
{
- $this->name = $name !== null ? Name::from($name) : null;
+ $this->name = $name !== null ? new Name($name) : null;
$this->isNullable = $name !== null && $isNullable;
}
}
diff --git a/src/Code/Variables/Variable.php b/src/Code/Variables/Variable.php
index dd0f90a..60d375c 100644
--- a/src/Code/Variables/Variable.php
+++ b/src/Code/Variables/Variable.php
@@ -1,6 +1,6 @@
type->removeArraySuffix());
+ return new Name($this->type->removeArraySuffix());
}
}
diff --git a/src/Code/Variables/WithTypeDeclaration.php b/src/Code/Variables/WithTypeDeclaration.php
index db88d15..462ca61 100644
--- a/src/Code/Variables/WithTypeDeclaration.php
+++ b/src/Code/Variables/WithTypeDeclaration.php
@@ -1,6 +1,6 @@
configuration = $configuration;
- }
-
- public function classDiagramGenerator(): ClassDiagramGenerator
- {
- return new ClassDiagramGenerator(
- $this->codeParser(),
- $this->digraphProcessor(),
- $this->imageProcessor()
- );
- }
-
- private function imageProcessor(): ImageProcessor
- {
- return $this->configuration->isDotProcessor() ? new DotProcessor() : new NeatoProcessor();
- }
-}
diff --git a/src/Configuration/ClassDiagramConfiguration.php b/src/Configuration/ClassDiagramConfiguration.php
index 6d55beb..6232c93 100644
--- a/src/Configuration/ClassDiagramConfiguration.php
+++ b/src/Configuration/ClassDiagramConfiguration.php
@@ -1,6 +1,6 @@
setImageProcessor($input['processor']);
+ $this->setImageProcessor($input['processor'] ?? '');
}
public function isDotProcessor(): bool
{
- return $this->imageProcessor->is('dot');
+ return $this->imageProcessor->isDot();
}
private function setImageProcessor(?string $imageProcessor): void
{
- $this->imageProcessor = ImageProcessorName::from($imageProcessor);
+ $this->imageProcessor = new ImageProcessorName($imageProcessor);
}
}
diff --git a/src/Configuration/DigraphBuilder.php b/src/Configuration/DigraphBuilder.php
index 9ed7e23..272aa07 100644
--- a/src/Configuration/DigraphBuilder.php
+++ b/src/Configuration/DigraphBuilder.php
@@ -1,6 +1,6 @@
parserBuilder = new ParserBuilder();
+ $this->configuration = $configuration;
}
- public function codeFinder(): CodeFinder
+ public function codeFinder(CodebaseDirectory $directory): CodeFinder
{
- return $this->configuration->searchRecursively() ? new CodeFinder() : new NonRecursiveCodeFinder();
+ return $this->configuration->searchRecursively()
+ ? SourceCodeFinder::recursive($directory)
+ : SourceCodeFinder::nonRecursive($directory);
}
- protected function digraphProcessor(): GraphvizProcessor
+ public function digraphProcessor(): GraphvizProcessor
{
- $associationsBuilder = $this->configuration->extractAssociations() ? new EdgesBuilder() : new NoAssociationsBuilder();
+ $associationsBuilder = $this->configuration->extractAssociations()
+ ? new EdgesBuilder()
+ : new NoAssociationsBuilder();
+
return new GraphvizProcessor(
new ClassGraphBuilder($associationsBuilder),
new InterfaceGraphBuilder(),
@@ -55,56 +56,44 @@ protected function digraphProcessor(): GraphvizProcessor
);
}
- protected function digraphStyle(): DigraphStyle
- {
- if ($this->configuration->hideEmptyBlocks()) {
- return new NonEmptyBlocksStyle($this->configuration->theme());
- }
- return new DefaultDigraphStyle($this->configuration->theme());
- }
-
- protected function codeParser(): CodeParser
+ public function codeParser(): CodeParser
{
- return new CodeParser($this->tokenParser(), $this->externalDefinitionsResolver());
+ return new CodeParser($this->tokenParser(), $this->externalDefinitionsResolvers());
}
- protected function tokenParser(): PhpParser
+ private function digraphStyle(): DigraphStyle
{
- $this->configureAttributes();
- $this->configureMethods();
- $this->configureFilters();
- return $this->parserBuilder->build();
+ if ($this->configuration->hideEmptyBlocks()) {
+ return DigraphStyle::withoutEmptyBlocks($this->configuration->theme());
+ }
+ return DigraphStyle::default($this->configuration->theme());
}
- private function configureAttributes(): void
+ private function tokenParser(): PhpCodeParser
{
+ $parserBuilder = new ParserBuilder();
if ($this->configuration->hideAttributes()) {
- $this->parserBuilder->excludeAttributes();
+ $parserBuilder->excludeAttributes();
}
- }
-
- private function configureMethods(): void
- {
if ($this->configuration->hideMethods()) {
- $this->parserBuilder->excludeMethods();
+ $parserBuilder->excludeMethods();
}
- }
-
- private function configureFilters(): void
- {
if ($this->configuration->hidePrivate()) {
- $this->parserBuilder->excludePrivateMembers();
+ $parserBuilder->excludePrivateMembers();
}
if ($this->configuration->hideProtected()) {
- $this->parserBuilder->excludeProtectedMembers();
+ $parserBuilder->excludeProtectedMembers();
}
+ return $parserBuilder->build();
}
- private function externalDefinitionsResolver(): ExternalDefinitionsResolver
+ /** @return RelationshipsResolver[] */
+ private function externalDefinitionsResolvers(): array
{
+ $resolvers = [new ExternalDefinitionsResolver()];
if ($this->configuration->extractAssociations()) {
- return new ExternalAssociationsResolver();
+ $resolvers[] = new ExternalAssociationsResolver();
}
- return new ExternalDefinitionsResolver();
+ return $resolvers;
}
}
diff --git a/src/Configuration/DigraphConfiguration.php b/src/Configuration/DigraphConfiguration.php
index 935ec25..5e1d5e1 100644
--- a/src/Configuration/DigraphConfiguration.php
+++ b/src/Configuration/DigraphConfiguration.php
@@ -1,6 +1,6 @@
hideEmptyBlocks;
}
- public function theme(): string
+ public function theme(): ThemeName
{
- return $this->theme->name();
+ return $this->theme;
}
- protected function setTheme(string $theme): void
+ private function setTheme(string $name): void
{
- $this->theme = ThemeName::from($theme);
+ $this->theme = new ThemeName($name);
}
}
diff --git a/src/Configuration/DotFileBuilder.php b/src/Configuration/DotFileBuilder.php
deleted file mode 100644
index c96812f..0000000
--- a/src/Configuration/DotFileBuilder.php
+++ /dev/null
@@ -1,24 +0,0 @@
-configuration = $configuration;
- }
-
- public function dotFileGenerator(): DotFileGenerator
- {
- return new DotFileGenerator($this->codeParser(), $this->digraphProcessor());
- }
-}
diff --git a/src/Console/Commands/GenerateClassDiagramCommand.php b/src/Console/Commands/GenerateClassDiagramCommand.php
index e98f397..b68740d 100644
--- a/src/Console/Commands/GenerateClassDiagramCommand.php
+++ b/src/Console/Commands/GenerateClassDiagramCommand.php
@@ -1,6 +1,6 @@
directory();
$classDiagramPath = $generatorInput->outputFile();
- $builder = new ClassDiagramBuilder(new ClassDiagramConfiguration($generatorInput->options()));
+ $configuration = new ClassDiagramConfiguration($generatorInput->options());
+ $builder = new DigraphBuilder(new DigraphConfiguration($generatorInput->options()));
- $codeFinder = $builder->codeFinder();
- $codeFinder->addDirectory(CodebaseDirectory::from($codebasePath));
+ $codeFinder = $builder->codeFinder($codebasePath);
- $classDiagramGenerator = $builder->classDiagramGenerator();
+ $classDiagramGenerator = new ClassDiagramGenerator(
+ $builder->codeParser(),
+ $builder->digraphProcessor(),
+ $configuration->isDotProcessor() ? new DotProcessor() : new NeatoProcessor()
+ );
$classDiagramGenerator->attach($this->display);
$classDiagramGenerator->generate($codeFinder, $classDiagramPath);
diff --git a/src/Console/Commands/GenerateDotFileCommand.php b/src/Console/Commands/GenerateDotFileCommand.php
index 178726b..7ea5077 100644
--- a/src/Console/Commands/GenerateDotFileCommand.php
+++ b/src/Console/Commands/GenerateDotFileCommand.php
@@ -1,15 +1,15 @@
directory();
$dotFilePath = $generatorInput->outputFile();
- $builder = new DotFileBuilder(new DigraphConfiguration($generatorInput->options()));
+ $builder = new DigraphBuilder(new DigraphConfiguration($generatorInput->options()));
- $dotFileGenerator = $builder->dotFileGenerator();
+ $dotFileGenerator = new DotFileGenerator($builder->codeParser(), $builder->digraphProcessor());
$dotFileGenerator->attach($this->display);
- $codeFinder = $builder->codeFinder();
- $codeFinder->addDirectory(CodebaseDirectory::from($codebasePath));
+ $codeFinder = $builder->codeFinder($codebasePath);
$dotFileGenerator->generate($codeFinder, $dotFilePath);
diff --git a/src/Console/Commands/GenerateStatisticsCommand.php b/src/Console/Commands/GenerateStatisticsCommand.php
index a4558de..7898e94 100644
--- a/src/Console/Commands/GenerateStatisticsCommand.php
+++ b/src/Console/Commands/GenerateStatisticsCommand.php
@@ -1,6 +1,6 @@
getArguments(), $input->getOptions());
- $codebasePath = $statisticsInput->directory();
$statisticsFilePath = $statisticsInput->outputFile();
- $recursive = $statisticsInput->recursive();
- $statisticsGenerator = new StatisticsGenerator(new CodeParser(), new StatisticsProcessor());
+ $statisticsGenerator = new StatisticsGenerator(new CodeParser(new PhpCodeParser()), new StatisticsProcessor());
$statisticsGenerator->attach($this->display);
- $codeFinder = $recursive ? new CodeFinder() : new NonRecursiveCodeFinder();
- $codeFinder->addDirectory(CodebaseDirectory::from($codebasePath));
+ $codeFinder = $statisticsInput->codeFinder();
$statisticsGenerator->generate($codeFinder, $statisticsFilePath);
diff --git a/src/Console/Commands/GeneratorCommand.php b/src/Console/Commands/GeneratorCommand.php
index 2bde590..0e33e71 100644
--- a/src/Console/Commands/GeneratorCommand.php
+++ b/src/Console/Commands/GeneratorCommand.php
@@ -1,6 +1,6 @@
setDirectory($arguments);
+ $this->directory = new CodebaseDirectory($arguments['directory'] ?? '');
$this->setOutputFile($arguments);
$this->options = $options;
}
- public function directory(): string
+ public function directory(): CodebaseDirectory
{
return $this->directory;
}
@@ -47,16 +46,6 @@ public function options(): array
return $this->options;
}
- /** @param string[] $arguments */
- private function setDirectory(array $arguments): void
- {
- Assert::stringNotEmpty(
- $arguments['directory'] ?? '',
- 'The directory with the code to be scanned cannot be empty'
- );
- $this->directory = $arguments['directory'];
- }
-
/** @param string[] $arguments */
private function setOutputFile(array $arguments): void
{
diff --git a/src/Console/Commands/StatisticsInput.php b/src/Console/Commands/StatisticsInput.php
index 3d2e01b..1908b55 100644
--- a/src/Console/Commands/StatisticsInput.php
+++ b/src/Console/Commands/StatisticsInput.php
@@ -1,24 +1,24 @@
setDirectory($arguments);
+ $this->directory = $arguments['directory'] ?? '';
+ $this->recursive = isset($options['recursive']) && (bool) $options['recursive'];
$this->setOutputFile($arguments);
- $this->setRecursive($options);
- }
-
- public function directory(): string
- {
- return $this->directory;
}
public function outputFile(): string
@@ -41,21 +36,6 @@ public function outputFile(): string
return $this->outputFile;
}
- public function recursive(): bool
- {
- return $this->recursive;
- }
-
- /** @param string[] $arguments */
- private function setDirectory(array $arguments): void
- {
- Assert::stringNotEmpty(
- $arguments['directory'] ?? '',
- 'The directory with the code to be scanned cannot be empty'
- );
- $this->directory = $arguments['directory'];
- }
-
/** @param string[] $arguments */
private function setOutputFile(array $arguments): void
{
@@ -66,9 +46,9 @@ private function setOutputFile(array $arguments): void
$this->outputFile = $arguments['output'];
}
- /** @param string[] $options */
- private function setRecursive(array $options): void
+ public function codeFinder(): CodeFinder
{
- $this->recursive = isset($options['recursive']) && (bool) $options['recursive'];
+ $directory = new CodebaseDirectory($this->directory);
+ return $this->recursive ? SourceCodeFinder::recursive($directory) : SourceCodeFinder::nonRecursive($directory);
}
}
diff --git a/src/Console/Commands/WithDigraphConfiguration.php b/src/Console/Commands/WithDigraphConfiguration.php
index 1b78556..02ba404 100644
--- a/src/Console/Commands/WithDigraphConfiguration.php
+++ b/src/Console/Commands/WithDigraphConfiguration.php
@@ -1,6 +1,6 @@
addOption(
diff --git a/src/Console/PhUmlApplication.php b/src/Console/PhUmlApplication.php
index 57ce56a..8482ec9 100644
--- a/src/Console/PhUmlApplication.php
+++ b/src/Console/PhUmlApplication.php
@@ -1,6 +1,6 @@
dotElements = [];
$this->associationsBuilder = $associationsBuilder ?? new NoAssociationsBuilder();
}
@@ -44,7 +45,7 @@ public function __construct(AssociationsBuilder $associationsBuilder = null)
* 4. The parent class, if any
* 5. The interfaces it implements, if any
*
- * @return \PhUml\Graphviz\HasDotRepresentation[]
+ * @return HasDotRepresentation[]
*/
public function extractFrom(ClassDefinition $class, Codebase $codebase): array
{
diff --git a/src/Graphviz/Builders/EdgesBuilder.php b/src/Graphviz/Builders/EdgesBuilder.php
index fdfb406..b5f70a0 100644
--- a/src/Graphviz/Builders/EdgesBuilder.php
+++ b/src/Graphviz/Builders/EdgesBuilder.php
@@ -1,6 +1,6 @@
engine = $engine ?? new TemplateEngine();
- $this->style = $style ?? new DefaultDigraphStyle();
+ $this->style = $style ?? DigraphStyle::default(new ThemeName('phuml'));
}
public function toDot(Digraph $digraph): string
diff --git a/src/Graphviz/Edge.php b/src/Graphviz/Edge.php
index 55b45c5..4d161e2 100644
--- a/src/Graphviz/Edge.php
+++ b/src/Graphviz/Edge.php
@@ -1,6 +1,6 @@
attributes = 'partials/_attributes.html.twig';
- $this->methods = 'partials/_methods.html.twig';
- }
-}
diff --git a/src/Graphviz/Styles/DigraphStyle.php b/src/Graphviz/Styles/DigraphStyle.php
index e3186ae..42c869f 100644
--- a/src/Graphviz/Styles/DigraphStyle.php
+++ b/src/Graphviz/Styles/DigraphStyle.php
@@ -1,6 +1,6 @@
theme = "{$theme}.html.twig";
- $this->setPartials();
+ return new DigraphStyle($theme, 'partials/_empty-attributes.html.twig', 'partials/_empty-methods.html.twig');
+ }
+
+ private function __construct(ThemeName $theme, string $attributesTemplate, string $methodsTemplate)
+ {
+ $this->theme = "{$theme->name()}.html.twig";
+ $this->attributes = $attributesTemplate;
+ $this->methods = $methodsTemplate;
}
public function attributes(): string
@@ -41,6 +50,4 @@ public function theme(): string
{
return $this->theme;
}
-
- abstract protected function setPartials(): void;
}
diff --git a/src/Graphviz/Styles/NonEmptyBlocksStyle.php b/src/Graphviz/Styles/NonEmptyBlocksStyle.php
deleted file mode 100644
index 1fa2375..0000000
--- a/src/Graphviz/Styles/NonEmptyBlocksStyle.php
+++ /dev/null
@@ -1,21 +0,0 @@
-attributes = 'partials/_empty-attributes.html.twig';
- $this->methods = 'partials/_empty-methods.html.twig';
- }
-}
diff --git a/src/Graphviz/Styles/ThemeName.php b/src/Graphviz/Styles/ThemeName.php
index 046de3c..f2874aa 100644
--- a/src/Graphviz/Styles/ThemeName.php
+++ b/src/Graphviz/Styles/ThemeName.php
@@ -1,6 +1,6 @@
name = $name;
}
public function name(): string
{
return $this->name;
}
-
- private function __construct(string $name)
- {
- if (! \in_array($name, self::$validNames, true)) {
- throw UnknownTheme::named($name, self::$validNames);
- }
- $this->name = $name;
- }
}
diff --git a/src/Graphviz/Styles/UnknownTheme.php b/src/Graphviz/Styles/UnknownTheme.php
index 075b3a7..5cfd917 100644
--- a/src/Graphviz/Styles/UnknownTheme.php
+++ b/src/Graphviz/Styles/UnknownTheme.php
@@ -1,6 +1,6 @@
name),
+ new ClassDefinitionName((string) $class->name),
$this->membersBuilder->methods($class->getMethods()),
$this->membersBuilder->constants($class->stmts),
- $class->extends !== null ? ClassDefinitionName::from((string) end($class->extends->parts)) : null,
+ $class->extends !== null ? new ClassDefinitionName((string) end($class->extends->parts)) : null,
$this->membersBuilder->attributes($class->stmts),
$this->buildInterfaces($class->implements),
$this->buildTraits($class->stmts)
diff --git a/src/Parser/Code/Builders/Filters/PrivateVisibilityFilter.php b/src/Parser/Code/Builders/Filters/PrivateVisibilityFilter.php
index 2052bcf..5059a2c 100644
--- a/src/Parser/Code/Builders/Filters/PrivateVisibilityFilter.php
+++ b/src/Parser/Code/Builders/Filters/PrivateVisibilityFilter.php
@@ -1,12 +1,14 @@
isPrivate();
+ if ($member instanceof ClassConst
+ || $member instanceof ClassMethod
+ || $member instanceof Property) {
+ return ! $member->isPrivate();
+ }
+
+ return false;
}
}
diff --git a/src/Parser/Code/Builders/Filters/ProtectedVisibilityFilter.php b/src/Parser/Code/Builders/Filters/ProtectedVisibilityFilter.php
index f1f285c..a1cd5de 100644
--- a/src/Parser/Code/Builders/Filters/ProtectedVisibilityFilter.php
+++ b/src/Parser/Code/Builders/Filters/ProtectedVisibilityFilter.php
@@ -1,20 +1,30 @@
isProtected();
+ if ($member instanceof ClassConst
+ || $member instanceof ClassMethod
+ || $member instanceof Property) {
+ return ! $member->isProtected();
+ }
+
+ return false;
}
}
diff --git a/src/Parser/Code/Builders/Filters/VisibilityFilter.php b/src/Parser/Code/Builders/Filters/VisibilityFilter.php
index 97d1bca..3bc0e89 100644
--- a/src/Parser/Code/Builders/Filters/VisibilityFilter.php
+++ b/src/Parser/Code/Builders/Filters/VisibilityFilter.php
@@ -1,17 +1,15 @@
name),
+ new InterfaceDefinitionName((string) $interface->name),
$this->membersBuilder->methods($interface->getMethods()),
$this->membersBuilder->constants($interface->stmts),
$this->buildInterfaces($interface->extends)
diff --git a/src/Parser/Code/Builders/Members/AttributesBuilder.php b/src/Parser/Code/Builders/Members/AttributesBuilder.php
index df8532e..05d169e 100644
--- a/src/Parser/Code/Builders/Members/AttributesBuilder.php
+++ b/src/Parser/Code/Builders/Members/AttributesBuilder.php
@@ -1,6 +1,6 @@
visibilityBuilder = $visibilityBuilder;
$this->visibilityFilters = $filters;
+ $this->typeBuilder = $typeBuilder;
}
/**
@@ -43,16 +46,14 @@ public function __construct(VisibilityBuilder $visibilityBuilder, VisibilityFilt
*/
public function build(array $parsedAttributes): array
{
- $attributes = array_filter($parsedAttributes, static function ($attribute): bool {
- return $attribute instanceof Property;
- });
+ $attributes = array_filter($parsedAttributes, static fn ($attribute): bool => $attribute instanceof Property);
return array_map(function (Property $attribute): Attribute {
- $name = "\${$attribute->props[0]->name}";
+ $variable = new Variable(
+ "\${$attribute->props[0]->name}",
+ $this->typeBuilder->fromAttributeType($attribute->type, $attribute->getDocComment())
+ );
$visibility = $this->visibilityBuilder->build($attribute);
- $comment = $attribute->getDocComment() === null ? null : $attribute->getDocComment()->getText();
- $docBlock = AttributeDocBlock::from($comment);
- $variable = new Variable($name, $docBlock->extractType());
return new Attribute($variable, $visibility, $attribute->isStatic());
}, $this->visibilityFilters->apply($attributes));
diff --git a/src/Parser/Code/Builders/Members/FilteredConstantsBuilder.php b/src/Parser/Code/Builders/Members/FilteredConstantsBuilder.php
index d731530..974b67c 100644
--- a/src/Parser/Code/Builders/Members/FilteredConstantsBuilder.php
+++ b/src/Parser/Code/Builders/Members/FilteredConstantsBuilder.php
@@ -1,6 +1,6 @@
'int',
'double' => 'float',
'string' => 'string',
];
- /** @var VisibilityBuilder */
- private $visibilityBuilder;
+ private VisibilityBuilder $visibilityBuilder;
- /** @var VisibilityFilters */
- private $visibilityFilters;
+ private VisibilityFilters $visibilityFilters;
public function __construct(VisibilityBuilder $visibilityBuilder, VisibilityFilters $filters)
{
@@ -44,17 +42,13 @@ public function __construct(VisibilityBuilder $visibilityBuilder, VisibilityFilt
*/
public function build(array $classAttributes): array
{
- $constants = array_filter($classAttributes, static function ($attribute): bool {
- return $attribute instanceof ClassConst;
- });
+ $constants = array_filter($classAttributes, static fn ($attribute): bool => $attribute instanceof ClassConst);
- return array_map(function (ClassConst $constant): Constant {
- return new Constant(
- (string) $constant->consts[0]->name,
- TypeDeclaration::from($this->determineType($constant->consts[0])),
- $this->visibilityBuilder->build($constant)
- );
- }, $this->visibilityFilters->apply($constants));
+ return array_map(fn (ClassConst $constant): Constant => new Constant(
+ (string) $constant->consts[0]->name,
+ TypeDeclaration::from($this->determineType($constant->consts[0])),
+ $this->visibilityBuilder->build($constant)
+ ), $this->visibilityFilters->apply($constants));
}
private function determineType(Const_ $constant): ?string
diff --git a/src/Parser/Code/Builders/Members/FilteredMethodsBuilder.php b/src/Parser/Code/Builders/Members/FilteredMethodsBuilder.php
index 1809d1f..79698d5 100644
--- a/src/Parser/Code/Builders/Members/FilteredMethodsBuilder.php
+++ b/src/Parser/Code/Builders/Members/FilteredMethodsBuilder.php
@@ -1,6 +1,6 @@
buildMethod($method);
- }, $this->visibilityFilters->apply($methods));
+ return array_map(
+ fn (ClassMethod $method): Method => $this->buildMethod($method),
+ $this->visibilityFilters->apply($methods)
+ );
}
private function buildMethod(ClassMethod $method): Method
{
$name = $method->name->name;
$visibility = $this->visibilityBuilder->build($method);
- $docBlock = $method->getDocComment() === null ? null : $method->getDocComment()->getText();
- $methodDocBlock = MethodDocBlock::from($docBlock);
- $returnType = $this->typeBuilder->fromMethodReturnType($method->returnType, $methodDocBlock);
- $parameters = $this->parametersBuilder->build($method->params, $methodDocBlock);
+ $docBlock = $method->getDocComment();
+ $returnType = $this->typeBuilder->fromMethodReturnType($method->returnType, $docBlock);
+ $parameters = $this->parametersBuilder->build($method->params, $docBlock);
switch (true) {
case $method->isAbstract():
return new Method($name, $visibility, $returnType, $parameters, true);
diff --git a/src/Parser/Code/Builders/Members/MethodsBuilder.php b/src/Parser/Code/Builders/Members/MethodsBuilder.php
index 929aace..609a768 100644
--- a/src/Parser/Code/Builders/Members/MethodsBuilder.php
+++ b/src/Parser/Code/Builders/Members/MethodsBuilder.php
@@ -1,6 +1,6 @@
getText());
if ($type === null) {
- return $docBlock->typeOfParameter($name);
+ return $methodDocBlock->typeOfParameter($name);
}
- return $this->fromParsedType($type);
+ $typeDeclaration = $this->fromParsedType($type);
+ if ($typeDeclaration->isBuiltInArray() && $methodDocBlock->hasTypeOfParameter($name)) {
+ return $methodDocBlock->typeOfParameter($name);
+ }
+ return $typeDeclaration;
}
/** @param Identifier|Name|NullableType|UnionType|null $type */
- public function fromMethodReturnType($type, MethodDocBlock $docBlock): TypeDeclaration
+ public function fromMethodReturnType($type, ?Doc $docBlock): TypeDeclaration
{
+ $methodDocBlock = new MethodDocBlock($docBlock === null ? null : $docBlock->getText());
if ($type === null) {
- return $docBlock->returnType();
+ return $methodDocBlock->returnType();
}
- return $this->fromParsedType($type);
+ $typeDeclaration = $this->fromParsedType($type);
+ if ($typeDeclaration->isBuiltInArray() && $methodDocBlock->hasReturnType()) {
+ return $methodDocBlock->returnType();
+ }
+ return $typeDeclaration;
}
/** @param Identifier|Name|NullableType|UnionType|null $type */
- private function fromParsedType($type): TypeDeclaration
+ public function fromAttributeType($type, ?Doc $docBlock): TypeDeclaration
{
- if ($type instanceof NullableType) {
- return TypeDeclaration::fromNullable((string) $type->type);
+ $attributeDocBlock = new AttributeDocBlock($docBlock === null ? null : $docBlock->getText());
+ if ($type === null) {
+ return $attributeDocBlock->attributeType();
}
- if ($type instanceof Name) {
- return TypeDeclaration::from($type->getLast());
+ $typeDeclaration = $this->fromParsedType($type);
+ if ($typeDeclaration->isBuiltInArray() && $attributeDocBlock->hasAttributeType()) {
+ return $attributeDocBlock->attributeType();
}
+ return $typeDeclaration;
+ }
- if ($type instanceof Identifier) {
- return TypeDeclaration::from((string) $type);
+ /** @param Identifier|Name|NullableType|UnionType|null $type */
+ private function fromParsedType($type): TypeDeclaration
+ {
+ switch (true) {
+ case $type instanceof NullableType:
+ return TypeDeclaration::fromNullable((string) $type->type);
+ case $type instanceof Name:
+ return TypeDeclaration::from($type->getLast());
+ case $type instanceof Identifier:
+ return TypeDeclaration::from((string) $type);
+ default:
+ throw UnsupportedType::declaredAs($type);
}
-
- throw UnsupportedType::declaredAs($type);
}
}
diff --git a/src/Parser/Code/Builders/Members/UnsupportedType.php b/src/Parser/Code/Builders/Members/UnsupportedType.php
index feedc2a..b447f24 100644
--- a/src/Parser/Code/Builders/Members/UnsupportedType.php
+++ b/src/Parser/Code/Builders/Members/UnsupportedType.php
@@ -1,6 +1,6 @@
filters as $filter) {
- $attributes = array_filter($attributes, static function (Stmt $member) use ($filter): bool {
- return $filter->accept($member);
- });
+ $attributes = array_filter($attributes, static fn (Stmt $member): bool => $filter->accept($member));
}
return $attributes;
}
diff --git a/src/Parser/Code/Builders/MembersBuilder.php b/src/Parser/Code/Builders/MembersBuilder.php
index 6f5c93b..e84cb36 100644
--- a/src/Parser/Code/Builders/MembersBuilder.php
+++ b/src/Parser/Code/Builders/MembersBuilder.php
@@ -1,6 +1,6 @@
constantsBuilder = $constantsBuilder ?? new FilteredConstantsBuilder($visibilityBuilder, $filters);
+ $typeBuilder = new TypeBuilder();
$this->attributesBuilder = $attributesBuilder ?? new FilteredAttributesBuilder(
$visibilityBuilder,
+ $typeBuilder,
$filters
);
- $typeBuilder = new TypeBuilder();
$this->methodsBuilder = $methodsBuilder ?? new FilteredMethodsBuilder(
new ParametersBuilder($typeBuilder),
$typeBuilder,
diff --git a/src/Parser/Code/Builders/Names/InterfaceNamesBuilder.php b/src/Parser/Code/Builders/Names/InterfaceNamesBuilder.php
index e20797e..4eaf7cc 100644
--- a/src/Parser/Code/Builders/Names/InterfaceNamesBuilder.php
+++ b/src/Parser/Code/Builders/Names/InterfaceNamesBuilder.php
@@ -1,6 +1,6 @@
getLast());
- }, $implements);
+ return array_map(static fn (Name $name): DefinitionName => new DefinitionName($name->getLast()), $implements);
}
}
diff --git a/src/Parser/Code/Builders/Names/TraitNamesBuilder.php b/src/Parser/Code/Builders/Names/TraitNamesBuilder.php
index 972bb9c..91c0db5 100644
--- a/src/Parser/Code/Builders/Names/TraitNamesBuilder.php
+++ b/src/Parser/Code/Builders/Names/TraitNamesBuilder.php
@@ -1,6 +1,6 @@
$node instanceof TraitUse);
if (count($useStatements) === 0) {
return [];
@@ -43,7 +41,7 @@ protected function buildTraits(array $nodes): array
private function traitNames(TraitUse $use, array $traits): array
{
foreach ($use->traits as $name) {
- $traits[] = TraitName::from($name->getLast());
+ $traits[] = new TraitName($name->getLast());
}
return $traits;
}
diff --git a/src/Parser/Code/Builders/TraitDefinitionBuilder.php b/src/Parser/Code/Builders/TraitDefinitionBuilder.php
index f5d564d..787b936 100644
--- a/src/Parser/Code/Builders/TraitDefinitionBuilder.php
+++ b/src/Parser/Code/Builders/TraitDefinitionBuilder.php
@@ -1,6 +1,6 @@
name),
+ new Name((string) $trait->name),
$this->membersBuilder->methods($trait->getMethods()),
$this->membersBuilder->attributes($trait->stmts),
$this->buildTraits($trait->stmts)
diff --git a/src/Parser/Code/ExternalAssociationsResolver.php b/src/Parser/Code/ExternalAssociationsResolver.php
index 60fb4ff..a15e68f 100644
--- a/src/Parser/Code/ExternalAssociationsResolver.php
+++ b/src/Parser/Code/ExternalAssociationsResolver.php
@@ -1,6 +1,6 @@
definitions() as $definition) {
+ if ($definition instanceof ClassDefinition) {
+ $this->resolveForClass($definition, $codebase);
+ }
+ }
+ }
+
+ private function resolveForClass(ClassDefinition $definition, Codebase $codebase): void
{
- parent::resolveForClass($definition, $codebase);
$this->resolveExternalAttributes($definition, $codebase);
$this->resolveExternalConstructorParameters($definition, $codebase);
}
@@ -34,7 +41,7 @@ private function resolveExternalAttributes(ClassDefinition $definition, Codebase
{
array_map(function (Attribute $attribute) use ($codebase): void {
if ($attribute->isAReference() && ! $codebase->has($attribute->referenceName())) {
- $codebase->add($this->externalClass($attribute->referenceName()));
+ $codebase->add(new ClassDefinition($attribute->referenceName()));
}
}, $definition->attributes());
}
@@ -43,7 +50,7 @@ private function resolveExternalConstructorParameters(ClassDefinition $definitio
{
array_map(function (Parameter $parameter) use ($codebase): void {
if ($parameter->isAReference() && ! $codebase->has($parameter->referenceName())) {
- $codebase->add($this->externalClass($parameter->referenceName()));
+ $codebase->add(new ClassDefinition($parameter->referenceName()));
}
}, $definition->constructorParameters());
}
diff --git a/src/Parser/Code/ExternalDefinitionsResolver.php b/src/Parser/Code/ExternalDefinitionsResolver.php
index e789b21..9a7fcdc 100644
--- a/src/Parser/Code/ExternalDefinitionsResolver.php
+++ b/src/Parser/Code/ExternalDefinitionsResolver.php
@@ -1,6 +1,6 @@
resolveForClass($definition, $codebase);
} elseif ($definition instanceof InterfaceDefinition) {
- $this->resolveForInterface($definition, $codebase);
+ $this->resolveExternalInterfaces($definition->parents(), $codebase);
} elseif ($definition instanceof TraitDefinition) {
- $this->resolveForTrait($definition, $codebase);
+ $this->resolveExternalTraits($definition->traits(), $codebase);
}
}
}
@@ -45,38 +44,22 @@ protected function resolveForClass(ClassDefinition $definition, Codebase $codeba
$this->resolveExternalParentClass($definition, $codebase);
}
- /**
- * It resolves for its parent interfaces
- */
- protected function resolveForInterface(InterfaceDefinition $definition, Codebase $codebase): void
- {
- $this->resolveExternalInterfaces($definition->parents(), $codebase);
- }
-
- /**
- * It resolves for the traits it uses
- */
- private function resolveForTrait(TraitDefinition $trait, Codebase $codebase): void
- {
- $this->resolveExternalTraits($trait->traits(), $codebase);
- }
-
- /** @param \PhUml\Code\Name[] $interfaces */
+ /** @param Name[] $interfaces */
private function resolveExternalInterfaces(array $interfaces, Codebase $codebase): void
{
array_map(function (Name $interface) use ($codebase): void {
if (! $codebase->has($interface)) {
- $codebase->add($this->externalInterface($interface));
+ $codebase->add(new InterfaceDefinition($interface));
}
}, $interfaces);
}
- /** @param \PhUml\Code\Name[] $traits */
+ /** @param Name[] $traits */
private function resolveExternalTraits(array $traits, Codebase $codebase): void
{
array_map(function (Name $trait) use ($codebase): void {
if (! $codebase->has($trait)) {
- $codebase->add($this->externalTrait($trait));
+ $codebase->add(new TraitDefinition($trait));
}
}, $traits);
}
@@ -88,22 +71,7 @@ private function resolveExternalParentClass(ClassDefinition $definition, Codebas
}
$parent = $definition->parent();
if (! $codebase->has($parent)) {
- $codebase->add($this->externalClass($parent));
+ $codebase->add(new ClassDefinition($parent));
}
}
-
- protected function externalInterface(Name $name): InterfaceDefinition
- {
- return new InterfaceDefinition($name);
- }
-
- protected function externalClass(Name $name): ClassDefinition
- {
- return new ClassDefinition($name);
- }
-
- protected function externalTrait(Name $name): TraitDefinition
- {
- return new TraitDefinition($name);
- }
}
diff --git a/src/Parser/Code/ParserBuilder.php b/src/Parser/Code/ParserBuilder.php
index 69c5eb2..7584785 100644
--- a/src/Parser/Code/ParserBuilder.php
+++ b/src/Parser/Code/ParserBuilder.php
@@ -1,6 +1,6 @@
attributesBuilder ?? new FilteredAttributesBuilder(
$visibilityBuilder,
+ $typeBuilder,
$filters
);
$membersBuilder = new MembersBuilder($constantsBuilder, $attributesBuilder, $methodsBuilder);
diff --git a/src/Parser/Code/Php5Traverser.php b/src/Parser/Code/Php5Traverser.php
deleted file mode 100644
index 8ad0375..0000000
--- a/src/Parser/Code/Php5Traverser.php
+++ /dev/null
@@ -1,32 +0,0 @@
-codebase = new Codebase();
- $this->traverser = new NodeTraverser();
- $this->traverser->addVisitor(new ClassVisitor($classBuilder, $this->codebase));
- $this->traverser->addVisitor(new InterfaceVisitor($interfaceBuilder, $this->codebase));
- $this->traverser->addVisitor(new TraitVisitor($traitBuilder, $this->codebase));
- }
-}
diff --git a/src/Parser/Code/PhpCodeParser.php b/src/Parser/Code/PhpCodeParser.php
index 9a9e738..0cb5aa0 100644
--- a/src/Parser/Code/PhpCodeParser.php
+++ b/src/Parser/Code/PhpCodeParser.php
@@ -1,16 +1,20 @@
create(ParserFactory::PREFER_PHP7),
- new Php5Traverser(
- $classBuilder ?? new ClassDefinitionBuilder(),
- $interfaceBuilder ?? new InterfaceDefinitionBuilder(),
- $traitBuilder ?? new TraitDefinitionBuilder()
- )
+ $this->parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7);
+ $this->traverser = new PhpTraverser(
+ $classBuilder ?? new ClassDefinitionBuilder(),
+ $interfaceBuilder ?? new InterfaceDefinitionBuilder(),
+ $traitBuilder ?? new TraitDefinitionBuilder()
);
}
+
+ public function parse(CodeFinder $finder): Codebase
+ {
+ foreach ($finder->files() as $code) {
+ /** @var Stmt[] $nodes Since the parser is run in throw errors mode */
+ $nodes = $this->parser->parse($code);
+ $this->traverser->traverse($nodes);
+ }
+ return $this->traverser->codebase();
+ }
}
diff --git a/src/Parser/Code/PhpParser.php b/src/Parser/Code/PhpParser.php
deleted file mode 100644
index 4517aeb..0000000
--- a/src/Parser/Code/PhpParser.php
+++ /dev/null
@@ -1,37 +0,0 @@
-parser = $parser;
- $this->traverser = $traverser;
- }
-
- public function parse(CodeFinder $finder): Codebase
- {
- foreach ($finder->files() as $code) {
- /** @var \PhpParser\Node\Stmt[] $nodes Since the parser is run in throw errors mode */
- $nodes = $this->parser->parse($code);
- $this->traverser->traverse($nodes);
- }
- return $this->traverser->codebase();
- }
-}
diff --git a/src/Parser/Code/PhpTraverser.php b/src/Parser/Code/PhpTraverser.php
index 4c22f20..f404724 100644
--- a/src/Parser/Code/PhpTraverser.php
+++ b/src/Parser/Code/PhpTraverser.php
@@ -1,37 +1,46 @@
codebase = new Codebase();
+ $this->traverser = new NodeTraverser();
+ $this->traverser->addVisitor(new ClassVisitor($classBuilder, $this->codebase));
+ $this->traverser->addVisitor(new InterfaceVisitor($interfaceBuilder, $this->codebase));
+ $this->traverser->addVisitor(new TraitVisitor($traitBuilder, $this->codebase));
+ }
/**
* It will create a `Definition` from the given nodes.
* It will add the `Definition` to the `Codebase`
*
- * @param \PhpParser\Node\Stmt[] $nodes
- * @see PhpParser::parse()
+ * @param Stmt[] $nodes
+ * @see PhpCodeParser::parse()
*/
public function traverse(array $nodes): void
{
diff --git a/src/Parser/Code/RelationshipsResolver.php b/src/Parser/Code/RelationshipsResolver.php
new file mode 100644
index 0000000..cf79448
--- /dev/null
+++ b/src/Parser/Code/RelationshipsResolver.php
@@ -0,0 +1,21 @@
+finder = new Finder();
- $this->files = [];
- }
-
- public function addDirectory(CodebaseDirectory $codebaseDirectory): void
- {
- $this->finder->in($codebaseDirectory->absolutePath())->files()->name('*.php')->sortByName();
- foreach ($this->finder as $file) {
- $this->files[] = $file->getContents();
- }
- }
-
/** @return string[] */
- public function files(): array
- {
- return $this->files;
- }
+ public function files(): array;
}
diff --git a/src/Parser/CodeParser.php b/src/Parser/CodeParser.php
index 1a2f40a..c401b35 100644
--- a/src/Parser/CodeParser.php
+++ b/src/Parser/CodeParser.php
@@ -1,6 +1,6 @@
parser = $parser ?? new PhpCodeParser();
- $this->resolver = $resolver ?? new ExternalDefinitionsResolver();
+ $this->parser = $parser;
+ $this->resolvers = $resolvers;
}
/**
@@ -45,7 +44,8 @@ public function __construct(PhpParser $parser = null, ExternalDefinitionsResolve
public function parse(CodeFinder $finder): Codebase
{
$codebase = $this->parser->parse($finder);
- $this->resolver->resolve($codebase);
+
+ array_map(static fn (RelationshipsResolver $resolver) => $resolver->resolve($codebase), $this->resolvers);
return $codebase;
}
diff --git a/src/Parser/CodebaseDirectory.php b/src/Parser/CodebaseDirectory.php
index 288c9a3..03a17a3 100644
--- a/src/Parser/CodebaseDirectory.php
+++ b/src/Parser/CodebaseDirectory.php
@@ -1,6 +1,6 @@
setDirectory($path);
}
public function absolutePath(): string
@@ -24,16 +24,16 @@ public function absolutePath(): string
return (string) $this->directory->getRealPath();
}
- private function __construct(string $path)
+ private function setDirectory(string $path): void
{
- $this->setDirectory(new SplFileInfo($path));
- }
-
- private function setDirectory(SplFileInfo $path): void
- {
- if (! $path->isDir()) {
- throw InvalidDirectory::notFoundAt($path);
+ Assert::stringNotEmpty(
+ $path,
+ 'The directory with the code to be scanned cannot be empty'
+ );
+ $directory = new SplFileInfo($path);
+ if (! $directory->isDir()) {
+ throw InvalidDirectory::notFoundAt($directory);
}
- $this->directory = $path;
+ $this->directory = $directory;
}
}
diff --git a/src/Parser/InvalidDirectory.php b/src/Parser/InvalidDirectory.php
index 38d82ea..4a3649f 100644
--- a/src/Parser/InvalidDirectory.php
+++ b/src/Parser/InvalidDirectory.php
@@ -1,6 +1,6 @@
finder->depth(0);
- }
-}
diff --git a/src/Parser/SourceCodeFinder.php b/src/Parser/SourceCodeFinder.php
new file mode 100644
index 0000000..b04ecd9
--- /dev/null
+++ b/src/Parser/SourceCodeFinder.php
@@ -0,0 +1,55 @@
+depth(0);
+ return new self($finder, $directory);
+ }
+
+ private function __construct(Finder $finder, CodebaseDirectory $directory)
+ {
+ $this->finder = $finder;
+ $this->directory = $directory;
+ }
+
+ /** @return string[] */
+ public function files(): array
+ {
+ $files = [];
+ $this->finder->in($this->directory->absolutePath())->files()->name('*.php')->sortByName();
+ foreach ($this->finder as $file) {
+ $files[] = $file->getContents();
+ }
+ return $files;
+ }
+}
diff --git a/src/Processors/DotProcessor.php b/src/Processors/DotProcessor.php
index 8d993b7..6002401 100644
--- a/src/Processors/DotProcessor.php
+++ b/src/Processors/DotProcessor.php
@@ -1,6 +1,6 @@
|null */
protected $process;
- /** @var Filesystem */
- private $fileSystem;
+ private Filesystem $fileSystem;
/** @param Process $process */
public function __construct(Process $process = null, Filesystem $fileSystem = null)
diff --git a/src/Processors/ImageProcessorName.php b/src/Processors/ImageProcessorName.php
index b180ae5..cd8f515 100644
--- a/src/Processors/ImageProcessorName.php
+++ b/src/Processors/ImageProcessorName.php
@@ -1,6 +1,6 @@
name === $name;
- }
-
- private function __construct(?string $name)
+ public function __construct(?string $name)
{
if (! \in_array($name, self::$names, true)) {
throw UnknownImageProcessor::named($name, self::$names);
}
$this->name = $name;
}
+
+ public function isDot(): bool
+ {
+ return $this->name === 'dot';
+ }
}
diff --git a/src/Processors/NeatoProcessor.php b/src/Processors/NeatoProcessor.php
index b497c5b..ea78d88 100644
--- a/src/Processors/NeatoProcessor.php
+++ b/src/Processors/NeatoProcessor.php
@@ -1,6 +1,6 @@
twig = $twig ?? new Twig(new FilesystemLoader(__DIR__ . '/../resources/templates'));
- $this->twig->addFilter(new Filter('whitespace', static function (string $html): ?string {
- return preg_replace('/\s\s+/', '', $html);
- }));
+ $this->twig->addFilter(new Filter(
+ 'whitespace',
+ static fn (string $html): ?string => preg_replace('/\s\s+/', '', $html)
+ ));
}
/** @param mixed[] $values */
diff --git a/src/Templates/TemplateFailure.php b/src/Templates/TemplateFailure.php
index 861bc08..86e12f9 100644
--- a/src/Templates/TemplateFailure.php
+++ b/src/Templates/TemplateFailure.php
@@ -1,6 +1,6 @@
expectException(LogicException::class);
- $this->generator->generate(new NonRecursiveCodeFinder(), 'wont-be-generated.png');
+ $this->generator->generate(new StringCodeFinder(), 'wont-be-generated.png');
}
/**
@@ -37,8 +41,8 @@ function it_fails_to_generate_diagram_if_a_command_is_not_provided()
function it_generates_a_class_diagram()
{
$this->generator->attach($this->prophesize(ProcessorProgressDisplay::class)->reveal());
- $finder = new NonRecursiveCodeFinder();
- $finder->addDirectory(CodebaseDirectory::from(__DIR__ . '/../../resources/.code/classes'));
+ $directory = new CodebaseDirectory(__DIR__ . '/../../resources/.code/classes');
+ $finder = SourceCodeFinder::nonRecursive($directory);
$diagram = __DIR__ . '/../../resources/.output/graphviz-dot.png';
$expectedDiagram = __DIR__ . '/../../resources/images/graphviz-dot.png';
@@ -54,8 +58,7 @@ function it_generates_a_class_diagram()
function it_generates_a_class_diagram_using_a_recursive_finder()
{
$this->generator->attach($this->prophesize(ProcessorProgressDisplay::class)->reveal());
- $codeFinder = new CodeFinder();
- $codeFinder->addDirectory(CodebaseDirectory::from(__DIR__ . '/../../resources/.code'));
+ $codeFinder = SourceCodeFinder::recursive(new CodebaseDirectory(__DIR__ . '/../../resources/.code'));
$diagram = __DIR__ . '/../../resources/.output/graphviz-dot-recursive.png';
$expectedDiagram = __DIR__ . '/../../resources/images/graphviz-dot-recursive.png';
@@ -68,12 +71,11 @@ function it_generates_a_class_diagram_using_a_recursive_finder()
function let()
{
$this->generator = new ClassDiagramGenerator(
- new CodeParser(),
+ new CodeParser(new PhpCodeParser(), [new ExternalDefinitionsResolver()]),
new GraphvizProcessor(new ClassGraphBuilder(new EdgesBuilder())),
new DotProcessor()
);
}
- /** @var ClassDiagramGenerator */
- private $generator;
+ private ClassDiagramGenerator $generator;
}
diff --git a/tests/integration/Generators/GenerateClassDiagramWithNeatoTest.php b/tests/integration/Generators/GenerateClassDiagramWithNeatoTest.php
index 6583614..5617add 100644
--- a/tests/integration/Generators/GenerateClassDiagramWithNeatoTest.php
+++ b/tests/integration/Generators/GenerateClassDiagramWithNeatoTest.php
@@ -1,6 +1,6 @@
expectException(LogicException::class);
- $this->generator->generate(new NonRecursiveCodeFinder(), 'wont-be-generated.png');
+ $this->generator->generate(new StringCodeFinder(), 'wont-be-generated.png');
}
/**
@@ -37,8 +41,8 @@ function it_fails_to_generate_diagram_if_a_command_is_not_provided()
function it_generates_a_class_diagram()
{
$this->generator->attach($this->prophesize(ProcessorProgressDisplay::class)->reveal());
- $finder = new NonRecursiveCodeFinder();
- $finder->addDirectory(CodebaseDirectory::from(__DIR__ . '/../../resources/.code/classes'));
+ $directory = new CodebaseDirectory(__DIR__ . '/../../resources/.code/classes');
+ $finder = SourceCodeFinder::nonRecursive($directory);
$diagram = __DIR__ . '/../../resources/.output/graphviz-neato.png';
$expectedDiagram = __DIR__ . '/../../resources/images/graphviz-neato.png';
@@ -54,8 +58,7 @@ function it_generates_a_class_diagram()
function it_generates_a_class_diagram_using_a_recursive_finder()
{
$this->generator->attach($this->prophesize(ProcessorProgressDisplay::class)->reveal());
- $codeFinder = new CodeFinder();
- $codeFinder->addDirectory(CodebaseDirectory::from(__DIR__ . '/../../resources/.code'));
+ $codeFinder = SourceCodeFinder::recursive(new CodebaseDirectory(__DIR__ . '/../../resources/.code'));
$diagram = __DIR__ . '/../../resources/.output/graphviz-neato-recursive.png';
$expectedDiagram = __DIR__ . '/../../resources/images/graphviz-neato-recursive.png';
@@ -68,12 +71,11 @@ function it_generates_a_class_diagram_using_a_recursive_finder()
function let()
{
$this->generator = new ClassDiagramGenerator(
- new CodeParser(),
+ new CodeParser(new PhpCodeParser(), [new ExternalDefinitionsResolver()]),
new GraphvizProcessor(new ClassGraphBuilder(new EdgesBuilder())),
new NeatoProcessor()
);
}
- /** @var ClassDiagramGenerator */
- private $generator;
+ private ClassDiagramGenerator $generator;
}
diff --git a/tests/integration/Generators/GenerateClassDiagramWithThemeTest.php b/tests/integration/Generators/GenerateClassDiagramWithThemeTest.php
index f31175d..b046fcd 100644
--- a/tests/integration/Generators/GenerateClassDiagramWithThemeTest.php
+++ b/tests/integration/Generators/GenerateClassDiagramWithThemeTest.php
@@ -1,6 +1,6 @@
addDirectory(CodebaseDirectory::from(__DIR__ . '/../../resources/.code'));
+ $codeFinder = SourceCodeFinder::recursive(new CodebaseDirectory(__DIR__ . '/../../resources/.code'));
$diagram = __DIR__ . '/../../resources/.output/graphviz-dot-php-theme.png';
$expectedDiagram = __DIR__ . '/../../resources/images/graphviz-dot-php-theme.png';
$generator = $this->createGenerator('php');
@@ -49,8 +53,7 @@ function it_generates_a_class_diagram_using_the_php_theme()
*/
function it_generates_a_class_diagram_using_the_classic_theme()
{
- $codeFinder = new CodeFinder();
- $codeFinder->addDirectory(CodebaseDirectory::from(__DIR__ . '/../../resources/.code'));
+ $codeFinder = SourceCodeFinder::recursive(new CodebaseDirectory(__DIR__ . '/../../resources/.code'));
$diagram = __DIR__ . '/../../resources/.output/graphviz-dot-classic-theme.png';
$expectedDiagram = __DIR__ . '/../../resources/images/graphviz-dot-classic-theme.png';
$generator = $this->createGenerator('classic');
@@ -63,12 +66,12 @@ function it_generates_a_class_diagram_using_the_classic_theme()
private function createGenerator(string $theme): ClassDiagramGenerator
{
$generator = new ClassDiagramGenerator(
- new CodeParser(),
+ new CodeParser(new PhpCodeParser(), [new ExternalDefinitionsResolver()]),
new GraphvizProcessor(
new ClassGraphBuilder(new EdgesBuilder()),
new InterfaceGraphBuilder(),
new TraitGraphBuilder(),
- new DigraphPrinter(new TemplateEngine(), new NonEmptyBlocksStyle($theme))
+ new DigraphPrinter(new TemplateEngine(), DigraphStyle::withoutEmptyBlocks(new ThemeName($theme)))
),
new DotProcessor()
);
diff --git a/tests/integration/Generators/GenerateClassDiagramWithoutEmptyBlocksTest.php b/tests/integration/Generators/GenerateClassDiagramWithoutEmptyBlocksTest.php
index de1f6d7..12857af 100644
--- a/tests/integration/Generators/GenerateClassDiagramWithoutEmptyBlocksTest.php
+++ b/tests/integration/Generators/GenerateClassDiagramWithoutEmptyBlocksTest.php
@@ -1,6 +1,6 @@
addDirectory(CodebaseDirectory::from(__DIR__ . '/../../resources/.code/classes'));
+ $directory = new CodebaseDirectory(__DIR__ . '/../../resources/.code/classes');
+ $finder = SourceCodeFinder::nonRecursive($directory);
$diagram = __DIR__ . '/../../resources/.output/graphviz-dot-without-empty-blocks.png';
$expectedDiagram = __DIR__ . '/../../resources/images/graphviz-dot-without-empty-blocks.png';
@@ -52,13 +55,12 @@ function let()
new ClassGraphBuilder(),
new InterfaceGraphBuilder(),
new TraitGraphBuilder(),
- new DigraphPrinter(new TemplateEngine(), new NonEmptyBlocksStyle())
+ new DigraphPrinter(new TemplateEngine(), DigraphStyle::withoutEmptyBlocks(new ThemeName('phuml')))
),
new DotProcessor()
);
$this->generator->attach($this->prophesize(ProcessorProgressDisplay::class)->reveal());
}
- /** @var ClassDiagramGenerator */
- private $generator;
+ private ?ClassDiagramGenerator $generator = null;
}
diff --git a/tests/integration/Parser/Code/Builders/Members/ParametersBuilderTest.php b/tests/integration/Parser/Code/Builders/Members/ParametersBuilderTest.php
index 58edb5a..cc14f36 100644
--- a/tests/integration/Parser/Code/Builders/Members/ParametersBuilderTest.php
+++ b/tests/integration/Parser/Code/Builders/Members/ParametersBuilderTest.php
@@ -1,6 +1,6 @@
build($parsedParameters, MethodDocBlock::from(null));
+ $parameters = $builder->build($parsedParameters, null);
$this->assertEquals('&$page: int', $parameters[0]->__toString());
$this->assertEquals('$size: int', $parameters[1]->__toString());
diff --git a/tests/integration/Parser/Code/Builders/Members/VisibilityBuilderTest.php b/tests/integration/Parser/Code/Builders/Members/VisibilityBuilderTest.php
index f200997..1da6357 100644
--- a/tests/integration/Parser/Code/Builders/Members/VisibilityBuilderTest.php
+++ b/tests/integration/Parser/Code/Builders/Members/VisibilityBuilderTest.php
@@ -1,6 +1,6 @@
identifier();
- $this->assertRegExp('/^[0-9A-Fa-f]{32}$/', $definitionId);
+ $this->assertMatchesRegularExpression('/^[0-9A-Fa-f]{32}$/', $definitionId);
}
/** @test */
@@ -68,6 +69,6 @@ function its_identifier_is_unique_per_object()
$this->assertEquals($definitionTwo->identifier(), $definitionTwo->identifier());
}
- /** @param \PhUml\Code\Methods\Method[] */
+ /** @param Method[] */
abstract protected function definition(array $methods = []): Definition;
}
diff --git a/tests/src/ContractTests/ImageProcessorTest.php b/tests/src/ContractTests/ImageProcessorTest.php
index 6d1da59..bf2c514 100644
--- a/tests/src/ContractTests/ImageProcessorTest.php
+++ b/tests/src/ContractTests/ImageProcessorTest.php
@@ -1,6 +1,6 @@
definitions() as $definition) {
+ if ($definition instanceof ClassDefinition) {
+ $this->resolveForClass($definition, $codebase);
+ } elseif ($definition instanceof InterfaceDefinition) {
+ $this->resolveExternalInterfaces($definition->parents(), $codebase);
+ } elseif ($definition instanceof TraitDefinition) {
+ $this->resolveExternalTraits($definition->traits(), $codebase);
+ }
+ }
}
- protected function externalClass(Name $name): ClassDefinition
+ /**
+ * It resolves for its parent class, its interfaces and traits
+ */
+ protected function resolveForClass(ClassDefinition $definition, Codebase $codebase): void
{
- return new NumericIdClass($name);
+ $this->resolveExternalInterfaces($definition->interfaces(), $codebase);
+ $this->resolveExternalTraits($definition->traits(), $codebase);
+ $this->resolveExternalParentClass($definition, $codebase);
+ }
+
+ /** @param Name[] $interfaces */
+ private function resolveExternalInterfaces(array $interfaces, Codebase $codebase): void
+ {
+ array_map(function (Name $interface) use ($codebase): void {
+ if (! $codebase->has($interface)) {
+ $codebase->add(new NumericIdInterface($interface));
+ }
+ }, $interfaces);
+ }
+
+ /** @param Name[] $traits */
+ private function resolveExternalTraits(array $traits, Codebase $codebase): void
+ {
+ array_map(function (Name $trait) use ($codebase): void {
+ if (! $codebase->has($trait)) {
+ $codebase->add(new TraitDefinition($trait));
+ }
+ }, $traits);
+ }
+
+ private function resolveExternalParentClass(ClassDefinition $definition, Codebase $codebase): void
+ {
+ if (! $definition->hasParent()) {
+ return;
+ }
+ $parent = $definition->parent();
+ if (! $codebase->has($parent)) {
+ $codebase->add(new NumericIdClass($parent));
+ }
}
}
diff --git a/tests/src/Fakes/NumericIdClass.php b/tests/src/Fakes/NumericIdClass.php
index 3ff6124..5faf26b 100644
--- a/tests/src/Fakes/NumericIdClass.php
+++ b/tests/src/Fakes/NumericIdClass.php
@@ -1,22 +1,31 @@
name),
+ new Name((string) $class->name),
$this->membersBuilder->methods($class->getMethods()),
$this->membersBuilder->constants($class->stmts),
- empty($class->extends) ? null : Name::from(end($class->extends->parts)),
+ empty($class->extends) ? null : new Name(end($class->extends->parts)),
$this->membersBuilder->attributes($class->stmts),
$this->buildInterfaces($class->implements),
$this->buildTraits($class->stmts)
diff --git a/tests/src/Fakes/NumericIdInterface.php b/tests/src/Fakes/NumericIdInterface.php
index 988f84e..a424afe 100644
--- a/tests/src/Fakes/NumericIdInterface.php
+++ b/tests/src/Fakes/NumericIdInterface.php
@@ -1,26 +1,27 @@
files = [];
@@ -20,4 +23,9 @@ public function add(string $definition)
{
$this->files[] = $definition;
}
+
+ public function files(): array
+ {
+ return $this->files;
+ }
}
diff --git a/tests/src/Fakes/TextInMemoryOutput.php b/tests/src/Fakes/TextInMemoryOutput.php
index 68f533b..1c5801e 100644
--- a/tests/src/Fakes/TextInMemoryOutput.php
+++ b/tests/src/Fakes/TextInMemoryOutput.php
@@ -1,6 +1,6 @@
assertRegExp(
+ $this->assertMatchesRegularExpression(
"/\"{$definition->identifier()}\" \\[label=<(?:.)+{$definition->name()}(?:.)+> shape=plaintext color=\"#[0-9a-f]{6}\"\\]/",
$dotLanguage,
"Definition {$definition->name()} with identifier {$definition->identifier()} cannot be found"
@@ -28,7 +28,7 @@ public function assertInheritance(
Definition $parent,
string $dotLanguage
): void {
- $this->assertRegExp(
+ $this->assertMatchesRegularExpression(
"/\"{$parent->identifier()}\" -> \"{$definition->identifier()}\" \\[dir=back arrowtail=empty style=solid color=\"#[0-9a-f]{6}\"\\]/",
$dotLanguage,
"{$definition->name()} identified by {$definition->identifier()} does not inherits {$parent->name()} identified by {$parent->identifier()}"
@@ -40,7 +40,7 @@ public function assertImplementation(
InterfaceDefinition $interface,
string $dotLanguage
): void {
- $this->assertRegExp(
+ $this->assertMatchesRegularExpression(
"/\"{$interface->identifier()}\" -> \"{$class->identifier()}\" \\[dir=back arrowtail=empty style=dashed color=\"#[0-9a-f]{6}\"\\]/",
$dotLanguage,
"{$class->name()} does not implements {$interface->name()}"
@@ -52,7 +52,7 @@ public function assertAssociation(
Definition $to,
string $dotLanguage
): void {
- $this->assertRegExp(
+ $this->assertMatchesRegularExpression(
"/\"{$from->identifier()}\" -> \"{$to->identifier()}\" \\[dir=back arrowtail=none style=solid color=\"#[0-9a-f]{6}\"\\]/",
$dotLanguage,
"There is no association between {$from->name()} and {$to->name()}"
@@ -64,7 +64,7 @@ public function assertUseTrait(
TraitDefinition $trait,
string $dotLanguage
): void {
- $this->assertRegExp(
+ $this->assertMatchesRegularExpression(
"/\"{$trait->identifier()}\" -> \"{$class->identifier()}\" \\[dir=back arrowtail=normal style=solid color=\"#[0-9a-f]{6}\"\\]/",
$dotLanguage,
"Class {$class->name()} does not use trait {$trait->name()}"
diff --git a/tests/src/Fakes/WithNumericIds.php b/tests/src/Fakes/WithNumericIds.php
index 1090dfa..47348ea 100644
--- a/tests/src/Fakes/WithNumericIds.php
+++ b/tests/src/Fakes/WithNumericIds.php
@@ -1,6 +1,6 @@
name),
+ new Name($this->name),
$this->methods,
$this->constants,
$this->parent,
@@ -59,11 +57,10 @@ public function build()
);
}
- /** @return NumericIdClass */
- public function buildWithNumericId()
+ public function buildWithNumericId(): NumericIdClass
{
return new NumericIdClass(
- Name::from($this->name),
+ new Name($this->name),
$this->methods,
$this->constants,
$this->parent,
diff --git a/tests/src/TestBuilders/DefinitionBuilder.php b/tests/src/TestBuilders/DefinitionBuilder.php
index 2326842..9c9dd8a 100644
--- a/tests/src/TestBuilders/DefinitionBuilder.php
+++ b/tests/src/TestBuilders/DefinitionBuilder.php
@@ -1,6 +1,6 @@
name),
+ new Name($this->name),
$this->methods,
$this->constants,
$this->parents
);
}
- /** @return NumericIdInterface */
- public function buildWithNumericId()
+ public function buildWithNumericId(): NumericIdInterface
{
return new NumericIdInterface(
- Name::from($this->name),
+ new Name($this->name),
$this->methods,
$this->constants,
$this->parents
diff --git a/tests/src/TestBuilders/MembersBuilder.php b/tests/src/TestBuilders/MembersBuilder.php
index 0da15c4..ad7e631 100644
--- a/tests/src/TestBuilders/MembersBuilder.php
+++ b/tests/src/TestBuilders/MembersBuilder.php
@@ -1,6 +1,6 @@
name),
+ new Name($this->name),
$this->methods,
$this->attributes,
$this->traits
@@ -46,7 +45,7 @@ public function build(): TraitDefinition
public function buildWithNumericId(): NumericIdTrait
{
return new NumericIdTrait(
- Name::from($this->name),
+ new Name($this->name),
$this->methods,
$this->attributes,
$this->traits
diff --git a/tests/src/TestBuilders/VariableBuilder.php b/tests/src/TestBuilders/VariableBuilder.php
index 154b967..1baccde 100644
--- a/tests/src/TestBuilders/VariableBuilder.php
+++ b/tests/src/TestBuilders/VariableBuilder.php
@@ -1,6 +1,6 @@
assertEquals(TypeDeclaration::from('TestClass'), $docBlock->extractType());
- $this->assertEquals(TypeDeclaration::from('AnotherClass'), $multiLineDocBlock->extractType());
+ $this->assertEquals(TypeDeclaration::from('TestClass'), $docBlock->attributeType());
+ $this->assertEquals(TypeDeclaration::from('AnotherClass'), $multiLineDocBlock->attributeType());
}
/** @test */
function it_extracts_an_array_type_declaration()
{
- $docBlock = AttributeDocBlock::from('/** @var TestClass[] $testClass */');
- $multiLineDocBlock = AttributeDocBlock::from('
+ $docBlock = new AttributeDocBlock('/** @var TestClass[] $testClass */');
+ $multiLineDocBlock = new AttributeDocBlock('
/**
* A description of the attribute
*
* @var AnotherClass[] $testClass
*/');
- $this->assertEquals(TypeDeclaration::from('TestClass[]'), $docBlock->extractType());
- $this->assertEquals(TypeDeclaration::from('AnotherClass[]'), $multiLineDocBlock->extractType());
+ $this->assertEquals(TypeDeclaration::from('TestClass[]'), $docBlock->attributeType());
+ $this->assertEquals(TypeDeclaration::from('AnotherClass[]'), $multiLineDocBlock->attributeType());
}
/** @test */
function it_knows_if_it_does_not_have_a_type_declaration()
{
- $docBlock = AttributeDocBlock::from('/** A description of the attribute */');
- $multiLineDocBlock = AttributeDocBlock::from('
+ $docBlock = new AttributeDocBlock('/** A description of the attribute */');
+ $multiLineDocBlock = new AttributeDocBlock('
/**
* A description of the attribute
*/');
- $this->assertEquals(TypeDeclaration::absent(), $docBlock->extractType());
- $this->assertEquals(TypeDeclaration::absent(), $multiLineDocBlock->extractType());
+ $this->assertEquals(TypeDeclaration::absent(), $docBlock->attributeType());
+ $this->assertEquals(TypeDeclaration::absent(), $multiLineDocBlock->attributeType());
}
}
diff --git a/tests/unit/Code/Attributes/AttributeTest.php b/tests/unit/Code/Attributes/AttributeTest.php
index a51dc71..04382e3 100644
--- a/tests/unit/Code/Attributes/AttributeTest.php
+++ b/tests/unit/Code/Attributes/AttributeTest.php
@@ -1,6 +1,6 @@
public()->withType('Directory[]')->build();
$this->assertTrue($typedArray->isAReference());
- $this->assertEquals(Name::from('Directory'), $typedArray->referenceName());
+ $this->assertEquals(new Name('Directory'), $typedArray->referenceName());
}
protected function memberWithoutType(): HasType
diff --git a/tests/unit/Code/Attributes/ConstantTest.php b/tests/unit/Code/Attributes/ConstantTest.php
index ddf847f..7dbac7c 100644
--- a/tests/unit/Code/Attributes/ConstantTest.php
+++ b/tests/unit/Code/Attributes/ConstantTest.php
@@ -1,6 +1,6 @@
interfaces();
@@ -67,8 +67,8 @@ function it_knows_its_constructor_has_no_parameters_if_no_constructor_is_specifi
function it_knows_the_interfaces_it_implements()
{
$interfaces = [
- Name::from('InterfaceOne'),
- Name::from('InterfaceTwo'),
+ new Name('InterfaceOne'),
+ new Name('InterfaceTwo'),
];
$classWithInterfaces = A::class('ClassWithInterfaces')
->implementing(...$interfaces)
@@ -83,7 +83,7 @@ function it_knows_the_interfaces_it_implements()
/** @test */
function it_does_not_extends_another_definition_by_default()
{
- $definitionWithoutParent = new ClassDefinition(Name::from('NoParentClass'));
+ $definitionWithoutParent = new ClassDefinition(new Name('NoParentClass'));
$hasParent = $definitionWithoutParent->hasParent();
@@ -93,7 +93,7 @@ function it_does_not_extends_another_definition_by_default()
/** @test */
function it_knows_its_parent()
{
- $parent = Name::from('ParentClass');
+ $parent = new Name('ParentClass');
$interfaceWithParent = A::class('WithParent')->extending($parent)->build();
$parentClass = $interfaceWithParent->parent();
@@ -112,17 +112,17 @@ function it_fails_to_get_its_parent_class_if_none_exist()
protected function definition(array $methods = []): Definition
{
- return new ClassDefinition(Name::from('ADefinition'), $methods);
+ return new ClassDefinition(new Name('ADefinition'), $methods);
}
protected function definitionWithConstants(array $constants = []): HasConstants
{
- return new ClassDefinition(Name::from('AnyClassDefinition'), [], $constants);
+ return new ClassDefinition(new Name('AnyClassDefinition'), [], $constants);
}
/** @param Attribute[] $attributes */
protected function definitionWithAttributes(array $attributes = []): HasAttributes
{
- return new ClassDefinition(Name::from('AClassWithAttributes'), [], [], null, $attributes);
+ return new ClassDefinition(new Name('AClassWithAttributes'), [], [], null, $attributes);
}
}
diff --git a/tests/unit/Code/CodebaseTest.php b/tests/unit/Code/CodebaseTest.php
index 673aa36..17a9676 100644
--- a/tests/unit/Code/CodebaseTest.php
+++ b/tests/unit/Code/CodebaseTest.php
@@ -1,6 +1,6 @@
hasParent();
@@ -29,8 +29,8 @@ function it_does_not_extends_another_definition_by_default()
/** @test */
function it_knows_its_parent()
{
- $parent = new InterfaceDefinition(Name::from('ParentInterface'));
- $anotherParent = new InterfaceDefinition(Name::from('AnotherParentInterface'));
+ $parent = new InterfaceDefinition(new Name('ParentInterface'));
+ $anotherParent = new InterfaceDefinition(new Name('AnotherParentInterface'));
$interfaceWithParent = A::interface('WithParent')
->extending($parent->name(), $anotherParent->name())
->build();
@@ -43,11 +43,11 @@ function it_knows_its_parent()
protected function definition(array $methods = []): Definition
{
- return new InterfaceDefinition(Name::from('ADefinition'), $methods);
+ return new InterfaceDefinition(new Name('ADefinition'), $methods);
}
protected function definitionWithConstants(array $constants = []): HasConstants
{
- return new InterfaceDefinition(Name::from('AnyClassDefinition'), [], $constants);
+ return new InterfaceDefinition(new Name('AnyClassDefinition'), [], $constants);
}
}
diff --git a/tests/unit/Code/Methods/MethodDocBlockTest.php b/tests/unit/Code/Methods/MethodDocBlockTest.php
index d3df84f..f1c2ae4 100644
--- a/tests/unit/Code/Methods/MethodDocBlockTest.php
+++ b/tests/unit/Code/Methods/MethodDocBlockTest.php
@@ -1,6 +1,6 @@
assertEquals(TypeDeclaration::from('string'), $docBlock->typeOfParameter('$name'));
$this->assertEquals(TypeDeclaration::from('Twig_Environment'), $docBlock->typeOfParameter('$engine'));
@@ -45,7 +45,7 @@ function it_defaults_to_no_type_when_no_param_tags_are_available()
*/
COMMENT;
- $docBlock = MethodDocBlock::from($comment);
+ $docBlock = new MethodDocBlock($comment);
$this->assertEquals(TypeDeclaration::absent(), $docBlock->typeOfParameter('$name'));
}
@@ -64,7 +64,7 @@ function it_extracts_both_parameter_type_and_return_type()
*/
COMMENT;
- $docBlock = MethodDocBlock::from($comment);
+ $docBlock = new MethodDocBlock($comment);
$this->assertEquals(TypeDeclaration::from('string'), $docBlock->typeOfParameter('$name'));
$this->assertEquals(TypeDeclaration::from('void'), $docBlock->returnType());
diff --git a/tests/unit/Code/Methods/MethodTest.php b/tests/unit/Code/Methods/MethodTest.php
index f17bee6..7c95d3e 100644
--- a/tests/unit/Code/Methods/MethodTest.php
+++ b/tests/unit/Code/Methods/MethodTest.php
@@ -1,6 +1,6 @@
true,
+ 'associations' => 'true',
+ 'hide-private' => true,
+ 'hide-protected' => 0,
+ 'hide-attributes' => 1,
+ 'hide-methods' => 'true',
+ 'hide-empty-blocks' => '',
+ 'theme' => 'phuml',
+ ]);
+ $builder = new DigraphBuilder($configuration);
+ $directory = new CodebaseDirectory(__DIR__ . '/../../resources/.code/interfaces/processor');
+
+ $codeFinder = $builder->codeFinder($directory);
+
+ $this->assertCount(2, $codeFinder->files());
+ }
+
+ /** @test */
+ function it_builds_a_code_finder_that_does_not_search_recursively()
+ {
+ $configuration = new DigraphConfiguration([
+ 'recursive' => false,
+ 'associations' => 'true',
+ 'hide-private' => true,
+ 'hide-protected' => 0,
+ 'hide-attributes' => 1,
+ 'hide-methods' => 'true',
+ 'hide-empty-blocks' => '',
+ 'theme' => 'phuml',
+ ]);
+ $builder = new DigraphBuilder($configuration);
+ $directory = new CodebaseDirectory(__DIR__ . '/../../resources/.code/interfaces/processor');
+
+ $codeFinder = $builder->codeFinder($directory);
+
+ $this->assertCount(1, $codeFinder->files());
+ }
+
+ /** @test */
+ function it_builds_a_parser_that_excludes_attributes()
+ {
+ $configuration = new DigraphConfiguration([
+ 'recursive' => 0,
+ 'associations' => 'true',
+ 'hide-private' => true,
+ 'hide-protected' => 0,
+ 'hide-attributes' => true,
+ 'hide-methods' => 'true',
+ 'hide-empty-blocks' => '',
+ 'theme' => 'phuml',
+ ]);
+ $builder = new DigraphBuilder($configuration);
+ $directory = new CodebaseDirectory(__DIR__ . '/../../resources/.code/interfaces/processor/graphviz');
+ $finder = $builder->codeFinder($directory);
+
+ $parser = $builder->codeParser();
+
+ $codebase = $parser->parse($finder);
+
+ $this->assertCount(1, $codebase->definitions());
+ $className = new Name('plGraphvizProcessorStyle');
+ $this->assertTrue($codebase->has($className));
+ $this->assertFalse($codebase->get($className)->hasAttributes());
+ }
+
+ /** @test */
+ function it_builds_a_parser_that_includes_attributes()
+ {
+ $configuration = new DigraphConfiguration([
+ 'recursive' => 0,
+ 'associations' => 'true',
+ 'hide-private' => 0,
+ 'hide-protected' => 0,
+ 'hide-attributes' => false,
+ 'hide-methods' => 'true',
+ 'hide-empty-blocks' => '',
+ 'theme' => 'phuml',
+ ]);
+ $builder = new DigraphBuilder($configuration);
+ $directory = new CodebaseDirectory(__DIR__ . '/../../resources/.code/interfaces/processor/graphviz');
+ $finder = $builder->codeFinder($directory);
+
+ $parser = $builder->codeParser();
+
+ $codebase = $parser->parse($finder);
+
+ $this->assertCount(1, $codebase->definitions());
+ $className = new Name('plGraphvizProcessorStyle');
+ $this->assertTrue($codebase->has($className));
+ $this->assertTrue($codebase->get($className)->hasAttributes());
+ }
+
+ /** @test */
+ function it_builds_a_parser_that_excludes_methods()
+ {
+ $configuration = new DigraphConfiguration([
+ 'recursive' => 0,
+ 'associations' => 'true',
+ 'hide-private' => [],
+ 'hide-protected' => 0,
+ 'hide-attributes' => false,
+ 'hide-methods' => 'true',
+ 'hide-empty-blocks' => '',
+ 'theme' => 'phuml',
+ ]);
+ $builder = new DigraphBuilder($configuration);
+ $directory = new CodebaseDirectory(__DIR__ . '/../../resources/.code/interfaces/processor/graphviz');
+ $finder = $builder->codeFinder($directory);
+
+ $parser = $builder->codeParser();
+
+ $codebase = $parser->parse($finder);
+
+ $this->assertCount(1, $codebase->definitions());
+ $className = new Name('plGraphvizProcessorStyle');
+ $this->assertTrue($codebase->has($className));
+ $this->assertEmpty($codebase->get($className)->methods());
+ }
+
+ /** @test */
+ function it_builds_a_parser_that_includes_methods()
+ {
+ $configuration = new DigraphConfiguration([
+ 'recursive' => 0,
+ 'associations' => 'true',
+ 'hide-private' => [],
+ 'hide-protected' => 0,
+ 'hide-attributes' => null,
+ 'hide-methods' => false,
+ 'hide-empty-blocks' => '',
+ 'theme' => 'phuml',
+ ]);
+ $builder = new DigraphBuilder($configuration);
+ $directory = new CodebaseDirectory(__DIR__ . '/../../resources/.code/interfaces/processor/graphviz');
+ $finder = $builder->codeFinder($directory);
+
+ $parser = $builder->codeParser();
+
+ $codebase = $parser->parse($finder);
+
+ $this->assertCount(1, $codebase->definitions());
+ $className = new Name('plGraphvizProcessorStyle');
+ $this->assertTrue($codebase->has($className));
+ $this->assertCount(1, $codebase->get($className)->methods());
+ }
+
+ /** @test */
+ function it_builds_a_parser_that_excludes_protected_members()
+ {
+ $configuration = new DigraphConfiguration([
+ 'recursive' => 0,
+ 'associations' => 'true',
+ 'hide-private' => [],
+ 'hide-protected' => true,
+ 'hide-attributes' => false,
+ 'hide-methods' => 'true',
+ 'hide-empty-blocks' => '',
+ 'theme' => 'phuml',
+ ]);
+ $builder = new DigraphBuilder($configuration);
+ $directory = new CodebaseDirectory(__DIR__ . '/../../resources/.code/exceptions/base');
+ $finder = $builder->codeFinder($directory);
+
+ $parser = $builder->codeParser();
+
+ $codebase = $parser->parse($finder);
+
+ $this->assertCount(2, $codebase->definitions());
+ $className = new Name('plBasePropertyException');
+ $this->assertTrue($codebase->has($className));
+ /** @var ClassDefinition $definition */
+ $definition = $codebase->get($className);
+ $this->assertCount(3, $definition->constants());
+ }
+
+ /** @test */
+ function it_builds_a_parser_that_includes_protected_members()
+ {
+ $configuration = new DigraphConfiguration([
+ 'recursive' => 0,
+ 'associations' => 'true',
+ 'hide-private' => [],
+ 'hide-protected' => false,
+ 'hide-attributes' => null,
+ 'hide-methods' => 'true',
+ 'hide-empty-blocks' => '',
+ 'theme' => 'phuml',
+ ]);
+ $builder = new DigraphBuilder($configuration);
+ $directory = new CodebaseDirectory(__DIR__ . '/../../resources/.code/exceptions/base');
+ $finder = $builder->codeFinder($directory);
+
+ $parser = $builder->codeParser();
+
+ $codebase = $parser->parse($finder);
+
+ $this->assertCount(2, $codebase->definitions());
+ $className = new Name('plBasePropertyException');
+ $this->assertTrue($codebase->has($className));
+ /** @var ClassDefinition $definition */
+ $definition = $codebase->get($className);
+ $this->assertCount(4, $definition->constants());
+ }
+
+ /** @test */
+ function it_builds_a_parser_that_includes_relationships_from_attributes_and_constructor_parameters()
+ {
+ $configuration = new DigraphConfiguration([
+ 'recursive' => 0,
+ 'associations' => true,
+ 'hide-private' => 0,
+ 'hide-protected' => null,
+ 'hide-attributes' => [],
+ 'hide-methods' => false,
+ 'hide-empty-blocks' => '',
+ 'theme' => 'phuml',
+ ]);
+ $builder = new DigraphBuilder($configuration);
+ $directory = new CodebaseDirectory(__DIR__ . '/../../resources/.code/classes/processor/graphviz/style');
+ $finder = $builder->codeFinder($directory);
+
+ $parser = $builder->codeParser();
+
+ $codebase = $parser->parse($finder);
+
+ $this->assertCount(3, $codebase->definitions());
+ $this->assertTrue($codebase->has(new Name('plStyleName')));
+ }
+
+ /** @test */
+ function it_builds_a_parser_that_excludes_relationships_from_attributes_and_constructor_parameters()
+ {
+ $configuration = new DigraphConfiguration([
+ 'recursive' => 0,
+ 'associations' => false,
+ 'hide-private' => 0,
+ 'hide-protected' => null,
+ 'hide-attributes' => [],
+ 'hide-methods' => false,
+ 'hide-empty-blocks' => '',
+ 'theme' => 'phuml',
+ ]);
+ $builder = new DigraphBuilder($configuration);
+ $directory = new CodebaseDirectory(__DIR__ . '/../../resources/.code/classes/processor/graphviz/style');
+ $finder = $builder->codeFinder($directory);
+
+ $parser = $builder->codeParser();
+
+ $codebase = $parser->parse($finder);
+
+ $this->assertCount(2, $codebase->definitions());
+ $this->assertFalse($codebase->has(new Name('plStyleName')));
+ }
+}
diff --git a/tests/unit/Configuration/DigraphConfigurationTest.php b/tests/unit/Configuration/DigraphConfigurationTest.php
index b358ed5..debabe4 100644
--- a/tests/unit/Configuration/DigraphConfigurationTest.php
+++ b/tests/unit/Configuration/DigraphConfigurationTest.php
@@ -1,6 +1,6 @@
'php',
]));
- $this->assertEquals('php', $configuration->theme());
+ $this->assertEquals('php', $configuration->theme()->name());
+ }
+
+ /** @test */
+ function it_casts_to_bool_all_options_but_theme()
+ {
+ $options = $this->options([
+ 'recursive' => 0,
+ 'associations' => 'true',
+ 'hide-private' => 1,
+ 'hide-protected' => [],
+ 'hide-attributes' => '',
+ 'hide-methods' => 'true',
+ 'hide-empty-blocks' => null,
+ ]);
+ $configuration = new DigraphConfiguration($options);
+
+ $this->assertFalse($configuration->searchRecursively());
+ $this->assertTrue($configuration->extractAssociations());
+ $this->assertTrue($configuration->hidePrivate());
+ $this->assertFalse($configuration->hideProtected());
+ $this->assertFalse($configuration->hideAttributes());
+ $this->assertTrue($configuration->hideMethods());
+ $this->assertFalse($configuration->hideEmptyBlocks());
}
private function options(array $override)
diff --git a/tests/unit/Console/Commands/GenerateClassDiagramCommandTest.php b/tests/unit/Console/Commands/GenerateClassDiagramCommandTest.php
index da548ed..bf94730 100644
--- a/tests/unit/Console/Commands/GenerateClassDiagramCommandTest.php
+++ b/tests/unit/Console/Commands/GenerateClassDiagramCommandTest.php
@@ -1,6 +1,6 @@
command = $application->find('phuml:statistics');
@@ -65,12 +66,9 @@ function configureCommandTester()
}
}
- /** @var GenerateStatisticsCommand */
- private $command;
+ private ?Command $command = null;
- /** @var CommandTester */
- private $tester;
+ private ?CommandTester $tester = null;
- /** @var string */
- private $statistics;
+ private ?string $statistics = null;
}
diff --git a/tests/unit/Console/ProgressDisplayTest.php b/tests/unit/Console/ProgressDisplayTest.php
new file mode 100644
index 0000000..a0b9b57
--- /dev/null
+++ b/tests/unit/Console/ProgressDisplayTest.php
@@ -0,0 +1,64 @@
+display->start();
+
+ $this->assertStringContainsString('Running... (This may take some time)', $this->output->fetch());
+ }
+
+ /** @test */
+ function it_displays_running_parser_message()
+ {
+ $this->display->runningParser();
+
+ $this->assertStringContainsString('Parsing codebase structure', $this->output->fetch());
+ }
+
+ /** @test */
+ function it_displays_running_processor_message()
+ {
+ $processor = $this->prophesize(Processor::class);
+ $processor->name()->willReturn('neato');
+
+ $this->display->runningProcessor($processor->reveal());
+
+ $this->assertStringContainsString('Running \'neato\' processor', $this->output->fetch());
+ }
+
+ /** @test */
+ function it_displays_saving_result_message()
+ {
+ $this->display->savingResult();
+
+ $this->assertStringContainsString('Writing generated data to disk', $this->output->fetch());
+ }
+
+ /** @before */
+ public function let()
+ {
+ $this->output = new BufferedOutput();
+ $this->display = new ProgressDisplay($this->output);
+ }
+
+ private BufferedOutput $output;
+
+ private ProgressDisplay $display;
+}
diff --git a/tests/unit/Generators/GenerateDotFileTest.php b/tests/unit/Generators/GenerateDotFileTest.php
index 17e135c..4ca72b5 100644
--- a/tests/unit/Generators/GenerateDotFileTest.php
+++ b/tests/unit/Generators/GenerateDotFileTest.php
@@ -1,6 +1,6 @@
expectException(LogicException::class);
- $generator->generate(new NonRecursiveCodeFinder(), 'wont-be-generated.gv');
+ $generator->generate(new StringCodeFinder(), 'wont-be-generated.gv');
}
/** @test */
function it_creates_the_dot_file_of_a_directory()
{
- $finder = new NonRecursiveCodeFinder();
- $finder->addDirectory(CodebaseDirectory::from($this->pathToCode));
+ $finder = SourceCodeFinder::nonRecursive(new CodebaseDirectory($this->pathToCode));
$this->generator->generate($finder, $this->pathToDotFile);
@@ -53,8 +54,7 @@ function it_creates_the_dot_file_of_a_directory()
/** @test */
function it_creates_the_dot_file_of_a_directory_using_a_recursive_finder()
{
- $finder = new CodeFinder();
- $finder->addDirectory(CodebaseDirectory::from($this->pathToCode));
+ $finder = SourceCodeFinder::recursive(new CodebaseDirectory($this->pathToCode));
$this->generator->generate($finder, $this->pathToDotFile);
@@ -69,6 +69,7 @@ function it_creates_the_dot_file_of_a_directory_using_a_recursive_finder()
$uml = A::numericIdClassNamed('plPhuml');
$dotProcessor = A::numericIdClassNamed('plDotProcessor');
$graphvizProcessor = A::numericIdClassNamed('plGraphvizProcessor');
+ $styleName = A::numericIdClassNamed('plStyleName');
$graphvizOptions = A::numericIdClassNamed('plGraphvizProcessorOptions');
$defaultStyle = A::numericIdClassNamed('plGraphvizProcessorDefaultStyle');
$neatoProcessor = A::numericIdClassNamed('plNeatoProcessor');
@@ -81,6 +82,7 @@ function it_creates_the_dot_file_of_a_directory_using_a_recursive_finder()
$digraphInDotFormat = file_get_contents($this->pathToDotFile);
$this->assertNode($base, $digraphInDotFormat);
$this->assertNode($structureGenerator, $digraphInDotFormat);
+ $this->assertNode($styleName, $digraphInDotFormat);
$this->assertNode($tokenParser, $digraphInDotFormat);
$this->assertInheritance($tokenParser, $structureGenerator, $digraphInDotFormat);
$this->assertNode($attribute, $digraphInDotFormat);
@@ -115,19 +117,16 @@ function let()
$this->generator = new DotFileGenerator(
new CodeParser(
new PhpCodeParser(new NumericIdClassDefinitionBuilder()),
- new ExternalNumericIdDefinitionsResolver()
+ [new ExternalNumericIdDefinitionsResolver()]
),
new GraphvizProcessor()
);
$this->generator->attach($this->prophesize(ProcessorProgressDisplay::class)->reveal());
}
- /** @var DotFileGenerator */
- private $generator;
+ private ?DotFileGenerator $generator = null;
- /** @var string */
- private $pathToDotFile;
+ private ?string $pathToDotFile = null;
- /** @var string */
- private $pathToCode;
+ private ?string $pathToCode = null;
}
diff --git a/tests/unit/Generators/GenerateStatisticsTest.php b/tests/unit/Generators/GenerateStatisticsTest.php
index f50d5f1..3b69f86 100644
--- a/tests/unit/Generators/GenerateStatisticsTest.php
+++ b/tests/unit/Generators/GenerateStatisticsTest.php
@@ -1,6 +1,6 @@
expectException(LogicException::class);
- $generator->generate(new NonRecursiveCodeFinder(), 'wont-be-generated.txt');
+ $generator->generate(new StringCodeFinder(), 'wont-be-generated.txt');
}
/** @test */
@@ -57,10 +62,9 @@ function it_shows_the_statistics_of_a_directory()
STATS;
- $generator = new StatisticsGenerator(new CodeParser(), new StatisticsProcessor());
+ $generator = new StatisticsGenerator(new CodeParser(new PhpCodeParser()), new StatisticsProcessor());
$generator->attach($this->prophesize(ProcessorProgressDisplay::class)->reveal());
- $finder = new NonRecursiveCodeFinder();
- $finder->addDirectory(CodebaseDirectory::from($this->pathToCode));
+ $finder = SourceCodeFinder::nonRecursive(new CodebaseDirectory($this->pathToCode));
$generator->generate($finder, $this->statisticsFile);
@@ -77,31 +81,31 @@ function it_shows_the_statistics_of_a_directory_using_a_recursive_finder()
General statistics
------------------
-Classes: 19
+Classes: 20
Interfaces: 0
-Attributes: 23 (4 are typed)
- * private: 17
+Attributes: 24 (5 are typed)
+ * private: 18
* protected: 2
* public: 4
-Functions: 86
+Functions: 87
* private: 36
* protected: 0
- * public: 50
+ * public: 51
Average statistics
------------------
-Attributes per class: 1.21
-Functions per class: 4.53
+Attributes per class: 1.2
+Functions per class: 4.35
STATS;
- $generator = new StatisticsGenerator(new CodeParser(), new StatisticsProcessor());
+ $parser = new CodeParser(new PhpCodeParser(), [new ExternalDefinitionsResolver()]);
+ $generator = new StatisticsGenerator($parser, new StatisticsProcessor());
$generator->attach($this->prophesize(ProcessorProgressDisplay::class)->reveal());
- $finder = new CodeFinder();
- $finder->addDirectory(CodebaseDirectory::from($this->pathToCode));
+ $finder = SourceCodeFinder::recursive(new CodebaseDirectory($this->pathToCode));
$generator->generate($finder, $this->statisticsFile);
@@ -109,15 +113,13 @@ function it_shows_the_statistics_of_a_directory_using_a_recursive_finder()
}
/** @before */
- function configure()
+ function let()
{
$this->statisticsFile = __DIR__ . '/../../resources/.output/statistics.txt';
$this->pathToCode = __DIR__ . '/../../resources/.code/classes';
}
- /** @var string */
- private $statisticsFile;
+ private ?string $statisticsFile = null;
- /** @var string */
- private $pathToCode;
+ private ?string $pathToCode = null;
}
diff --git a/tests/unit/Graphviz/Builders/ClassGraphBuilderTest.php b/tests/unit/Graphviz/Builders/ClassGraphBuilderTest.php
index 39bae6f..8ea86f0 100644
--- a/tests/unit/Graphviz/Builders/ClassGraphBuilderTest.php
+++ b/tests/unit/Graphviz/Builders/ClassGraphBuilderTest.php
@@ -1,6 +1,6 @@
printer->toDot($digraph);
- $this->assertRegExp('/^digraph "([0-9a-f]){40}"/', $dotLanguage);
+ $this->assertMatchesRegularExpression('/^digraph "([0-9a-f]){40}"/', $dotLanguage);
$this->assertStringContainsString('splines = true;
overlap = false;
mindist = 0.6;', $dotLanguage);
@@ -299,6 +299,5 @@ function let()
$this->printer = new DigraphPrinter();
}
- /** @var DigraphPrinter */
- private $printer;
+ private ?DigraphPrinter $printer = null;
}
diff --git a/tests/unit/Graphviz/EdgeTest.php b/tests/unit/Graphviz/EdgeTest.php
index 9fb6371..a22f782 100644
--- a/tests/unit/Graphviz/EdgeTest.php
+++ b/tests/unit/Graphviz/EdgeTest.php
@@ -1,6 +1,6 @@
build($parsedClass);
$expectedClassWithTraits = A::class('AClassWithTraits')
- ->using(TraitName::from('ATrait'), TraitName::from('AnotherTrait'))
+ ->using(new TraitName('ATrait'), new TraitName('AnotherTrait'))
->build();
$this->assertEquals($expectedClassWithTraits, $class);
}
@@ -57,9 +57,9 @@ function it_builds_a_class_with_traits_from_multiple_use_statements()
$classWithTwoUseTraitStatements = A::class('AClassWithTraits')
->using(
- TraitName::from('ATrait'),
- TraitName::from('AnotherTrait'),
- TraitName::from('ThirdTrait')
+ new TraitName('ATrait'),
+ new TraitName('AnotherTrait'),
+ new TraitName('ThirdTrait')
)
->build();
$this->assertEquals($classWithTwoUseTraitStatements, $class);
diff --git a/tests/unit/Parser/Code/Builders/Filters/PrivateVisibilityFilterTest.php b/tests/unit/Parser/Code/Builders/Filters/PrivateVisibilityFilterTest.php
new file mode 100644
index 0000000..a605766
--- /dev/null
+++ b/tests/unit/Parser/Code/Builders/Filters/PrivateVisibilityFilterTest.php
@@ -0,0 +1,22 @@
+assertFalse($filter->accept(new Nop()));
+ }
+}
diff --git a/tests/unit/Parser/Code/Builders/Filters/ProtectedVisibilityFilterTest.php b/tests/unit/Parser/Code/Builders/Filters/ProtectedVisibilityFilterTest.php
new file mode 100644
index 0000000..1654187
--- /dev/null
+++ b/tests/unit/Parser/Code/Builders/Filters/ProtectedVisibilityFilterTest.php
@@ -0,0 +1,22 @@
+assertFalse($filter->accept(new Nop()));
+ }
+}
diff --git a/tests/unit/Parser/Code/Builders/Members/FilteredAttributesBuilderTest.php b/tests/unit/Parser/Code/Builders/Members/FilteredAttributesBuilderTest.php
index 1aab9a8..ff4861b 100644
--- a/tests/unit/Parser/Code/Builders/Members/FilteredAttributesBuilderTest.php
+++ b/tests/unit/Parser/Code/Builders/Members/FilteredAttributesBuilderTest.php
@@ -1,6 +1,6 @@
typeBuilder->fromAttributeType(new Identifier('ClassDefinition'), null);
+ $typeB = $this->typeBuilder->fromAttributeType(
+ new Identifier('ClassDefinition'),
+ new Doc('/** @var OutdatedTypeFromComment */')
+ );
+ $typeC = $this->typeBuilder->fromAttributeType(
+ new Name(ClassDefinition::class),
+ new Doc('/** @var OutdatedTypeFromComment */')
+ );
+ $typeD = $this->typeBuilder->fromAttributeType(
+ new NullableType('ClassDefinition'),
+ new Doc('/** @var AnotherTypeFromComment */')
+ );
+
+ $this->assertEquals($expectedType, $typeA);
+ $this->assertEquals($expectedType, $typeB);
+ $this->assertEquals($expectedType, $typeC);
+ $this->assertEquals($expectedNullableType, $typeD);
+ }
+
+ /** @test */
+ function it_uses_type_in_an_attribute_doc_block_instead_of_generic_array_type_from_declaration()
+ {
+ $type = $this->typeBuilder->fromAttributeType(
+ new Identifier('array'),
+ new Doc('/** @var ClassDefinition[] */')
+ );
+
+ $this->assertEquals(TypeDeclaration::from('ClassDefinition[]'), $type);
+ }
+
+ /** @test */
+ function it_uses_type_in_method_return_dock_block_instead_generic_array_type_from_declaration()
+ {
+ $type = $this->typeBuilder->fromMethodReturnType(
+ new Identifier('array'),
+ new Doc('/** @return ClassDefinition[] */')
+ );
+
+ $this->assertEquals(TypeDeclaration::from('ClassDefinition[]'), $type);
+ }
+
+ /** @test */
+ function it_uses_type_in_method_parameter_dock_block_instead_generic_array_type_from_declaration()
+ {
+ $type = $this->typeBuilder->fromMethodParameter(
+ new Identifier('array'),
+ new Doc('/** @param ClassDefinition[] $definitions */'),
+ '$definitions'
+ );
+
+ $this->assertEquals(TypeDeclaration::from('ClassDefinition[]'), $type);
+ }
+
+ /** @before */
+ function let()
+ {
+ $this->typeBuilder = new TypeBuilder();
+ }
+
+ private TypeBuilder $typeBuilder;
+}
diff --git a/tests/unit/Parser/Code/Builders/TraitDefinitionBuilderTest.php b/tests/unit/Parser/Code/Builders/TraitDefinitionBuilderTest.php
index 5edbab7..7440200 100644
--- a/tests/unit/Parser/Code/Builders/TraitDefinitionBuilderTest.php
+++ b/tests/unit/Parser/Code/Builders/TraitDefinitionBuilderTest.php
@@ -1,6 +1,6 @@
using(
- TraitName::from('ATrait'),
- TraitName::from('AnotherTrait'),
- TraitName::from('ThirdTrait')
+ new TraitName('ATrait'),
+ new TraitName('AnotherTrait'),
+ new TraitName('ThirdTrait')
)
->build();
$this->assertEquals($traitUsingOtherTraits, $trait);
@@ -107,6 +107,5 @@ function let()
$this->builder = new TraitDefinitionBuilder();
}
- /** @var TraitDefinitionBuilder */
- private $builder;
+ private ?TraitDefinitionBuilder $builder = null;
}
diff --git a/tests/unit/Parser/Code/ExternalAssociationsResolverTest.php b/tests/unit/Parser/Code/ExternalAssociationsResolverTest.php
index 66e17ee..9ee6fb9 100644
--- a/tests/unit/Parser/Code/ExternalAssociationsResolverTest.php
+++ b/tests/unit/Parser/Code/ExternalAssociationsResolverTest.php
@@ -1,6 +1,6 @@
resolve($codebase);
- $this->assertTrue($codebase->has(Name::from('ReferenceA')));
- $this->assertTrue($codebase->has(Name::from('ReferenceB')));
- $this->assertTrue($codebase->has(Name::from('ReferenceC')));
+ $this->assertTrue($codebase->has(new Name('ReferenceA')));
+ $this->assertTrue($codebase->has(new Name('ReferenceB')));
+ $this->assertTrue($codebase->has(new Name('ReferenceC')));
}
/** @test */
@@ -54,9 +54,9 @@ function it_adds_external_constructor_parameters()
$resolver->resolve($codebase);
$this->assertCount(4, $codebase->definitions());
- $this->assertTrue($codebase->has(Name::from('ReferenceA')));
- $this->assertTrue($codebase->has(Name::from('ReferenceB')));
- $this->assertTrue($codebase->has(Name::from('ReferenceC')));
+ $this->assertTrue($codebase->has(new Name('ReferenceA')));
+ $this->assertTrue($codebase->has(new Name('ReferenceB')));
+ $this->assertTrue($codebase->has(new Name('ReferenceC')));
}
/** @test */
@@ -76,6 +76,6 @@ function it_removes_the_suffix_from_array_references()
$resolver->resolve($codebase);
$this->assertCount(2, $codebase->definitions());
$this->assertTrue($codebase->has($class->name()));
- $this->assertTrue($codebase->has(Name::from('Reference')));
+ $this->assertTrue($codebase->has(new Name('Reference')));
}
}
diff --git a/tests/unit/Parser/Code/ExternalDefinitionsResolverTest.php b/tests/unit/Parser/Code/ExternalDefinitionsResolverTest.php
index b3275f8..7dc5f14 100644
--- a/tests/unit/Parser/Code/ExternalDefinitionsResolverTest.php
+++ b/tests/unit/Parser/Code/ExternalDefinitionsResolverTest.php
@@ -1,6 +1,6 @@
add(A::class('AClass')
- ->implementing(Name::from('AnExternalInterface'), Name::from('AnExistingInterface'))
+ ->implementing(new Name('AnExternalInterface'), new Name('AnExistingInterface'))
->build());
$codebase->add(A::interface('AnInterface')
- ->extending(Name::from('AnotherExternalInterface'))->build());
+ ->extending(new Name('AnotherExternalInterface'))->build());
$codebase->add(A::interface('AnExistingInterface')->build());
$resolver->resolve($codebase);
@@ -56,8 +56,8 @@ function it_adds_external_classes()
$codebase = new Codebase();
$resolver = new ExternalDefinitionsResolver();
- $codebase->add(A::class('AClass')->extending(Name::from('AnExternalClass'))->build());
- $codebase->add(A::class('AnotherClass')->extending(Name::from('AnotherExternalClass'))->build());
+ $codebase->add(A::class('AClass')->extending(new Name('AnExternalClass'))->build());
+ $codebase->add(A::class('AnotherClass')->extending(new Name('AnotherExternalClass'))->build());
$resolver->resolve($codebase);
@@ -73,10 +73,10 @@ function it_adds_external_traits()
$resolver = new ExternalDefinitionsResolver();
$codebase->add(A::class('AClass')
- ->using(Name::from('AnExternalTrait'), Name::from('AnExistingTrait'))
+ ->using(new Name('AnExternalTrait'), new Name('AnExistingTrait'))
->build());
$codebase->add(A::trait('ATrait')
- ->using(Name::from('AnotherExternalTrait'))->build());
+ ->using(new Name('AnotherExternalTrait'))->build());
$codebase->add(A::trait('AnExistingTrait')->build());
$resolver->resolve($codebase);
diff --git a/tests/unit/Parser/Code/Php5ParserTest.php b/tests/unit/Parser/Code/PhpCodeParserTest.php
similarity index 94%
rename from tests/unit/Parser/Code/Php5ParserTest.php
rename to tests/unit/Parser/Code/PhpCodeParserTest.php
index bbd7fca..afa3008 100644
--- a/tests/unit/Parser/Code/Php5ParserTest.php
+++ b/tests/unit/Parser/Code/PhpCodeParserTest.php
@@ -1,6 +1,6 @@
finder = new NonRecursiveCodeFinder();
- $this->finder->addDirectory(CodebaseDirectory::from(__DIR__ . '/../../../resources/.code/classes'));
+ $directory = new CodebaseDirectory(__DIR__ . '/../../../resources/.code/classes');
+ $this->finder = SourceCodeFinder::nonRecursive($directory);
}
- /** @var NonRecursiveCodeFinder */
- private $finder;
+ private CodeFinder $finder;
}
diff --git a/tests/unit/Parser/Code/Visitors/ClassVisitorTest.php b/tests/unit/Parser/Code/Visitors/ClassVisitorTest.php
index d3fbe63..611cc0c 100644
--- a/tests/unit/Parser/Code/Visitors/ClassVisitorTest.php
+++ b/tests/unit/Parser/Code/Visitors/ClassVisitorTest.php
@@ -1,6 +1,6 @@
addDirectory(CodebaseDirectory::from("{$this->pathToCode}/classes"));
+ $finder = SourceCodeFinder::nonRecursive(new CodebaseDirectory("{$this->pathToCode}/classes"));
$this->assertCount(2, $finder->files());
- $this->assertRegExp('/class plBase/', $finder->files()[0]);
- $this->assertRegExp('/class plPhuml/', $finder->files()[1]);
+ $this->assertMatchesRegularExpression('/class plBase/', $finder->files()[0]);
+ $this->assertMatchesRegularExpression('/class plPhuml/', $finder->files()[1]);
}
/** @test */
function it_finds_files_recursively()
{
- $finder = new CodeFinder();
-
- $finder->addDirectory(CodebaseDirectory::from("{$this->pathToCode}/interfaces"));
+ $finder = SourceCodeFinder::recursive(new CodebaseDirectory("{$this->pathToCode}/interfaces"));
$this->assertCount(7, $finder->files());
- $this->assertRegExp('/interface plCompatible/', $finder->files()[0]);
- $this->assertRegExp('/trait plDiskWriter/', $finder->files()[1]);
- $this->assertRegExp('/trait plFileWriter/', $finder->files()[2]);
- $this->assertRegExp('/abstract class plStructureGenerator/', $finder->files()[3]);
- $this->assertRegExp('/abstract class plProcessor/', $finder->files()[4]);
- $this->assertRegExp('/abstract class plExternalCommandProcessor/', $finder->files()[5]);
- $this->assertRegExp('/abstract class plGraphvizProcessorStyle/', $finder->files()[6]);
+ $this->assertMatchesRegularExpression('/interface plCompatible/', $finder->files()[0]);
+ $this->assertMatchesRegularExpression('/trait plDiskWriter/', $finder->files()[1]);
+ $this->assertMatchesRegularExpression('/trait plFileWriter/', $finder->files()[2]);
+ $this->assertMatchesRegularExpression('/abstract class plStructureGenerator/', $finder->files()[3]);
+ $this->assertMatchesRegularExpression('/abstract class plProcessor/', $finder->files()[4]);
+ $this->assertMatchesRegularExpression('/abstract class plExternalCommandProcessor/', $finder->files()[5]);
+ $this->assertMatchesRegularExpression('/abstract class plGraphvizProcessorStyle/', $finder->files()[6]);
}
/** @before */
diff --git a/tests/unit/Parser/CodeParserTest.php b/tests/unit/Parser/CodeParserTest.php
index e0b3440..ddc67dd 100644
--- a/tests/unit/Parser/CodeParserTest.php
+++ b/tests/unit/Parser/CodeParserTest.php
@@ -1,6 +1,6 @@
parser = new CodeParser();
+ $this->parser = new CodeParser(new PhpCodeParser());
$this->finder = new StringCodeFinder();
}
- /** @var CodeParser */
- private $parser;
+ private ?CodeParser $parser = null;
- /** @var StringCodeFinder */
- private $finder;
+ private ?StringCodeFinder $finder = null;
}
diff --git a/tests/unit/Processors/DotProcessorTest.php b/tests/unit/Processors/DotProcessorTest.php
index fe82c19..bc3e4ca 100644
--- a/tests/unit/Processors/DotProcessorTest.php
+++ b/tests/unit/Processors/DotProcessorTest.php
@@ -1,6 +1,6 @@