Skip to content

Commit

Permalink
Merge pull request #47 from peter-gribanov/phpstan_configuration
Browse files Browse the repository at this point in the history
Test Configuration class with PHPStan
  • Loading branch information
peter-gribanov committed Feb 7, 2020
2 parents b11ea7e + c257513 commit 6f99de8
Show file tree
Hide file tree
Showing 11 changed files with 303 additions and 115 deletions.
9 changes: 9 additions & 0 deletions .phpstan/default.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
includes:
- ../vendor/phpstan/phpstan-phpunit/extension.neon
- ../vendor/phpstan/phpstan-phpunit/rules.neon

parameters:
level: 7
paths:
- ../src
- ../tests
8 changes: 8 additions & 0 deletions .phpstan/symfony_2.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# config for Symfone 2.8 - 3.4

includes:
- default.neon

parameters:
ignoreErrors:
- '#Class Symfony\\Component\\Config\\Definition\\Builder\\TreeBuilder does not have a constructor and must be instantiated without any parameters\.#'
4 changes: 4 additions & 0 deletions .phpstan/symfony_3.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# config for Symfone 3.0 - 3.4

includes:
- symfony_2.neon
4 changes: 4 additions & 0 deletions .phpstan/symfony_4.1.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# config for Symfone 4.0 - 4.1

includes:
- symfony_2.neon
4 changes: 4 additions & 0 deletions .phpstan/symfony_4.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# config for Symfone 4.2 - 4.4

includes:
- default.neon
9 changes: 9 additions & 0 deletions .phpstan/symfony_5.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# config for Symfone 5.0

includes:
- default.neon

parameters:
ignoreErrors:
- '#Call to an undefined method Symfony\\Component\\Config\\Definition\\Builder\\TreeBuilder::root\(\)\.#'
- '#Class Symfony\\Component\\Config\\Definition\\Builder\\TreeBuilder constructor invoked with 0 parameters, 1\-3 required\.#'
142 changes: 123 additions & 19 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,57 +20,161 @@ before_install:
- if [ -n "$GH_TOKEN" ]; then composer config github-oauth.github.com ${GH_TOKEN}; fi;
- if [ -n "$SYMFONY_VERSION" ]; then composer require "symfony/symfony:${SYMFONY_VERSION}" --dev --no-update; fi;

install:
- travis_retry composer install --prefer-dist --no-interaction --no-scripts --no-progress
install: travis_retry composer install --prefer-dist --no-interaction --no-scripts --no-progress

jobs:
include:
- stage: Code Quality
name: PHP CS Fixer
before_script: wget https://cs.symfony.com/download/php-cs-fixer-v2.phar -O php-cs-fixer
- stage: Test Symfony
env: SYMFONY_VERSION=2.8.*
php: 7.1
script:
- php php-cs-fixer fix --diff --dry-run -v
- vendor/bin/phpunit --coverage-clover build/coverage-clover.xml
- vendor/phpstan/phpstan/phpstan analyse -c .phpstan/symfony_2.neon
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.2.0/php-coveralls.phar
- php ocular.phar code-coverage:upload --format=php-clover build/coverage-clover.xml
- php php-coveralls.phar -v -c .coveralls.yml

- stage: Code Quality
name: PHPStan
script: vendor/phpstan/phpstan/phpstan analyse
- stage: Test Symfony
env: SYMFONY_VERSION=3.0.*
php: 7.1
script:
- vendor/bin/phpunit --coverage-clover build/coverage-clover.xml
- vendor/phpstan/phpstan/phpstan analyse -c .phpstan/symfony_3.neon
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.2.0/php-coveralls.phar
- php ocular.phar code-coverage:upload --format=php-clover build/coverage-clover.xml
- php php-coveralls.phar -v -c .coveralls.yml

- stage: Test
env: SYMFONY_VERSION=2.8.*
- stage: Test Symfony
env: SYMFONY_VERSION=3.1.*
php: 7.1
script: vendor/bin/phpunit --coverage-clover build/coverage-clover.xml
script:
- vendor/bin/phpunit --coverage-clover build/coverage-clover.xml
- vendor/phpstan/phpstan/phpstan analyse -c .phpstan/symfony_3.neon
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.2.0/php-coveralls.phar
- php ocular.phar code-coverage:upload --format=php-clover build/coverage-clover.xml
- php php-coveralls.phar -v -c .coveralls.yml

- stage: Test
- stage: Test Symfony
env: SYMFONY_VERSION=3.2.*
php: 7.1
script:
- vendor/bin/phpunit --coverage-clover build/coverage-clover.xml
- vendor/phpstan/phpstan/phpstan analyse -c .phpstan/symfony_3.neon
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.2.0/php-coveralls.phar
- php ocular.phar code-coverage:upload --format=php-clover build/coverage-clover.xml
- php php-coveralls.phar -v -c .coveralls.yml

- stage: Test Symfony
env: SYMFONY_VERSION=3.3.*
php: 7.1
script:
- vendor/bin/phpunit --coverage-clover build/coverage-clover.xml
- vendor/phpstan/phpstan/phpstan analyse -c .phpstan/symfony_3.neon
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.2.0/php-coveralls.phar
- php ocular.phar code-coverage:upload --format=php-clover build/coverage-clover.xml
- php php-coveralls.phar -v -c .coveralls.yml

- stage: Test Symfony
env: SYMFONY_VERSION=3.4.*
php: 7.1
script: vendor/bin/phpunit --coverage-clover build/coverage-clover.xml
script:
- vendor/bin/phpunit --coverage-clover build/coverage-clover.xml
- vendor/phpstan/phpstan/phpstan analyse -c .phpstan/symfony_3.neon
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.2.0/php-coveralls.phar
- php ocular.phar code-coverage:upload --format=php-clover build/coverage-clover.xml
- php php-coveralls.phar -v -c .coveralls.yml

- stage: Test
- stage: Test Symfony
env: SYMFONY_VERSION=4.0.*
php: 7.1
script:
- vendor/bin/phpunit --coverage-clover build/coverage-clover.xml
- vendor/phpstan/phpstan/phpstan analyse -c .phpstan/symfony_4.1.neon
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.2.0/php-coveralls.phar
- php ocular.phar code-coverage:upload --format=php-clover build/coverage-clover.xml
- php php-coveralls.phar -v -c .coveralls.yml

- stage: Test Symfony
env: SYMFONY_VERSION=4.1.*
php: 7.1
script:
- vendor/bin/phpunit --coverage-clover build/coverage-clover.xml
- vendor/phpstan/phpstan/phpstan analyse -c .phpstan/symfony_4.1.neon
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.2.0/php-coveralls.phar
- php ocular.phar code-coverage:upload --format=php-clover build/coverage-clover.xml
- php php-coveralls.phar -v -c .coveralls.yml

- stage: Test Symfony
env: SYMFONY_VERSION=4.2.*
php: 7.1
script:
- vendor/bin/phpunit --coverage-clover build/coverage-clover.xml
- vendor/phpstan/phpstan/phpstan analyse -c .phpstan/symfony_4.neon
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.2.0/php-coveralls.phar
- php ocular.phar code-coverage:upload --format=php-clover build/coverage-clover.xml
- php php-coveralls.phar -v -c .coveralls.yml

- stage: Test Symfony
env: SYMFONY_VERSION=4.3.*
php: 7.1
script:
- vendor/bin/phpunit --coverage-clover build/coverage-clover.xml
- vendor/phpstan/phpstan/phpstan analyse -c .phpstan/symfony_4.neon
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.2.0/php-coveralls.phar
- php ocular.phar code-coverage:upload --format=php-clover build/coverage-clover.xml
- php php-coveralls.phar -v -c .coveralls.yml

- stage: Test Symfony
env: SYMFONY_VERSION=4.4.*
php: 7.1
script: vendor/bin/phpunit --coverage-clover build/coverage-clover.xml
script:
- vendor/bin/phpunit --coverage-clover build/coverage-clover.xml
- vendor/phpstan/phpstan/phpstan analyse -c .phpstan/symfony_4.neon
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.2.0/php-coveralls.phar
- php ocular.phar code-coverage:upload --format=php-clover build/coverage-clover.xml
- php php-coveralls.phar -v -c .coveralls.yml

- stage: Test
- stage: Test Symfony
env: SYMFONY_VERSION=5.0.*
php: 7.2
script: vendor/bin/phpunit --coverage-clover build/coverage-clover.xml
script:
- vendor/bin/phpunit --coverage-clover build/coverage-clover.xml
- vendor/phpstan/phpstan/phpstan analyse -c .phpstan/symfony_5.neon
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.2.0/php-coveralls.phar
- php ocular.phar code-coverage:upload --format=php-clover build/coverage-clover.xml
- php php-coveralls.phar -v -c .coveralls.yml
- php php-coveralls.phar -v -c .coveralls.yml

- stage: Code Quality
name: PHP CS Fixer
before_script: wget https://cs.symfony.com/download/php-cs-fixer-v2.phar -O php-cs-fixer
script: php php-cs-fixer fix --diff --dry-run -v

- stage: Code Quality
name: PHPStan
php: 7.2
env: SYMFONY_VERSION=~5.0
script: vendor/phpstan/phpstan/phpstan analyse
1 change: 0 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
"symfony/filesystem": "~2.3|~3.0|~4.0|~5.0"
},
"require-dev": {
"roave/security-advisories": "dev-master",
"phpunit/phpunit": "~7.0|~8.0",
"phpstan/phpstan": "^0.12",
"phpstan/phpstan-phpunit": "^0.12"
Expand Down
12 changes: 1 addition & 11 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -1,12 +1,2 @@
includes:
- vendor/phpstan/phpstan-phpunit/extension.neon
- vendor/phpstan/phpstan-phpunit/rules.neon

parameters:
level: 7
paths:
- src
- tests
excludes_analyse:
# heavily dependent on the version of Symfony
- src/DependencyInjection/Configuration
- .phpstan/symfony_5.neon
102 changes: 74 additions & 28 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,8 @@ public function __construct(?string $cache_dir)
*/
public function getConfigTreeBuilder(): TreeBuilder
{
$tree_builder = new TreeBuilder('gpslab_geoip');

if (method_exists($tree_builder, 'getRootNode')) {
// Symfony 4.2 +
$root_node = $tree_builder->getRootNode();
} else {
// Symfony 4.1 and below
$root_node = $tree_builder->root('gpslab_geoip');
}
$tree_builder = $this->createTreeBuilder('gpslab_geoip');
$root_node = $this->getRootNode($tree_builder, 'gpslab_geoip');

$this->normalizeDefaultDatabase($root_node);
$this->normalizeRootConfigurationToDefaultDatabase($root_node);
Expand All @@ -60,9 +53,8 @@ public function getConfigTreeBuilder(): TreeBuilder
$root_node->fixXmlConfig('locale');
$locales = $root_node->children()->arrayNode('locales');
$locales->prototype('scalar');
$locales
->treatNullLike([])
->defaultValue(['en']);
$locales->treatNullLike([]);
$locales->defaultValue(['en']);

$root_node->children()->scalarNode('license');

Expand All @@ -80,20 +72,11 @@ public function getConfigTreeBuilder(): TreeBuilder
*/
private function getDatabaseNode(): ArrayNodeDefinition
{
$tree_builder = new TreeBuilder('databases');

if (method_exists($tree_builder, 'getRootNode')) {
// Symfony 4.2 +
$root_node = $tree_builder->getRootNode();
} else {
// Symfony 4.1 and below
$root_node = $tree_builder->root('databases');
}

$tree_builder = $this->createTreeBuilder('databases');
$root_node = $this->getRootNode($tree_builder, 'databases');
$root_node->useAttributeAsKey('name');

/** @var ArrayNodeDefinition $database_node */
$database_node = $root_node->prototype('array');
$database_node = $this->arrayPrototype($root_node);

$this->normalizeUrl($database_node);
$this->normalizePath($database_node);
Expand All @@ -109,10 +92,8 @@ private function getDatabaseNode(): ArrayNodeDefinition
$database_node->fixXmlConfig('locale');
$locales = $database_node->children()->arrayNode('locales');
$locales->prototype('scalar');
$locales
->treatNullLike([])
->requiresAtLeastOneElement()
->defaultValue(['en']);
$locales->treatNullLike([]);
$locales->defaultValue(['en']);

$database_node->children()->scalarNode('license');

Expand All @@ -121,6 +102,71 @@ private function getDatabaseNode(): ArrayNodeDefinition
return $root_node;
}

/**
* @param string $name
*
* @return TreeBuilder
*/
private function createTreeBuilder(string $name): TreeBuilder
{
// Symfony 4.2 +
if (method_exists(TreeBuilder::class, '__construct')) {
return new TreeBuilder($name);
}

// Symfony 4.1 and below
return new TreeBuilder();
}

/**
* @param TreeBuilder $tree_builder
* @param string $name
*
* @return ArrayNodeDefinition
*/
private function getRootNode(TreeBuilder $tree_builder, string $name): ArrayNodeDefinition
{
if (method_exists($tree_builder, 'getRootNode')) {
// Symfony 4.2 +
$root = $tree_builder->getRootNode();
} else {
// Symfony 4.1 and below
$root = $tree_builder->root($name);
}

// @codeCoverageIgnoreStart
if (!($root instanceof ArrayNodeDefinition)) { // should be always false
throw new \RuntimeException(sprintf('The root node should be instance of %s, got %s instead.', ArrayNodeDefinition::class, get_class($root)));
}
// @codeCoverageIgnoreEnd

return $root;
}

/**
* @param ArrayNodeDefinition $root_node
*
* @return ArrayNodeDefinition
*/
private function arrayPrototype(ArrayNodeDefinition $root_node): ArrayNodeDefinition
{
// Symfony 3.3 +
if (method_exists($root_node, 'arrayPrototype')) {
return $root_node->arrayPrototype();
}

// Symfony 3.2 and below
$node = $root_node->prototype('array');

// @codeCoverageIgnoreStart
if (!($node instanceof ArrayNodeDefinition)) { // should be always false
throw new \RuntimeException(sprintf('The "array" prototype should be instance of %s, got %s instead.', ArrayNodeDefinition::class, get_class($node)));
}
// @codeCoverageIgnoreEnd

return $node;
}

/**
* Normalize default_database from databases.
*
Expand Down
Loading

0 comments on commit 6f99de8

Please sign in to comment.