diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..a8d57dd
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,9 @@
+version: 2
+updates:
+
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "weekly"
+ labels:
+ - "dependencies"
diff --git a/.github/workflows/php-cs-fixer.yml b/.github/workflows/php-cs-fixer.yml
new file mode 100644
index 0000000..e834bc8
--- /dev/null
+++ b/.github/workflows/php-cs-fixer.yml
@@ -0,0 +1,27 @@
+name: PHP-CS-Fixer
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+ branches: [ main ]
+
+jobs:
+ php-cs-fixer:
+ name: PHP-CS-Fixer
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: '8.3'
+ coverage: none
+ tools: composer:v2
+
+ - name: Install dependencies
+ run: composer install --prefer-dist --no-progress
+
+ - name: Run PHP-CS-Fixer
+ run: composer cs-check
diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml
new file mode 100644
index 0000000..3854536
--- /dev/null
+++ b/.github/workflows/phpstan.yml
@@ -0,0 +1,27 @@
+name: PHPStan
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+ branches: [ main ]
+
+jobs:
+ phpstan:
+ name: PHPStan
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: '8.3'
+ coverage: none
+ tools: composer:v2
+
+ - name: Install dependencies
+ run: composer install --prefer-dist --no-progress
+
+ - name: Run PHPStan
+ run: composer phpstan
diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml
new file mode 100644
index 0000000..a85fab0
--- /dev/null
+++ b/.github/workflows/phpunit.yml
@@ -0,0 +1,27 @@
+name: PHPUnit
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+ branches: [ main ]
+
+jobs:
+ phpunit:
+ name: PHPUnit
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: '8.3'
+ coverage: none
+ tools: composer:v2
+
+ - name: Install dependencies
+ run: composer install --prefer-dist --no-progress
+
+ - name: Run PHPUnit
+ run: composer test
diff --git a/.github/workflows/rector.yml b/.github/workflows/rector.yml
new file mode 100644
index 0000000..074798a
--- /dev/null
+++ b/.github/workflows/rector.yml
@@ -0,0 +1,27 @@
+name: Rector
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+ branches: [ main ]
+
+jobs:
+ rector:
+ name: Rector
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: '8.3'
+ coverage: none
+ tools: composer:v2
+
+ - name: Install dependencies
+ run: composer install --prefer-dist --no-progress
+
+ - name: Run Rector
+ run: composer rector-dry-run
diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
deleted file mode 100644
index cf1a1d8..0000000
--- a/.github/workflows/test.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-name: test
-on:
- push:
-
-jobs:
- test:
- strategy:
- matrix:
- php: ['8.0', '8.2']
- composer: ['--prefer-lowest', '']
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - uses: shivammathur/setup-php@v2
- with:
- php-version: ${{ matrix.php }}
- tools: composer:v2
- - run: composer update ${{ matrix.composer }}
- - run: composer validate
- - run: vendor/bin/php-cs-fixer fix --dry-run --diff
diff --git a/.gitignore b/.gitignore
index 3f1433d..54f5fb2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,8 @@ vendor/
.php-cs-fixer.cache
composer.lock
+.idea
+.phpstan-cache
+
+/vendor/
+/.phpunit.cache/
diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php
index 78d4513..a7656b6 100644
--- a/.php-cs-fixer.dist.php
+++ b/.php-cs-fixer.dist.php
@@ -1,11 +1,13 @@
in('src')
-;
+require_once __DIR__ . '/vendor/autoload.php';
-$config = new Valantic\PhpCsFixerConfig\Config();
+use Valantic\PhpCsFixerConfig\ConfigFactory;
-return $config
- ->setFinder($finder)
-;
+return ConfigFactory::createValanticConfig()
+ ->setFinder(
+ PhpCsFixer\Finder::create()
+ ->in(__DIR__ . '/src')
+ ->in(__DIR__ . '/tests')
+ )
+ ->setRiskyAllowed(true);
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..3be2557
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2025 valantic CEC Schweiz AG
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
index e298fcc..e915bc1 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,65 @@
-# php-cs-fixer-config
+# PHP-CS-Fixer Config for Valantic Projects
+
+This package provides standard PHP-CS-Fixer configurations used in projects built by Valantic.
+
+## Installation
+
+```bash
+composer require --dev valantic/php-cs-fixer-config
+```
+
+> **Note:** This package requires PHP 8.1 or higher.
+
+## Usage
+
+Create a `.php-cs-fixer.php` or `.php-cs-fixer.dist.php` file in your project root with one of the following configurations:
+
+### Basic Configuration
+
+```php
+ false,
+ // Add your custom rules here
+ ])
+ ->setFinder(
+ PhpCsFixer\Finder::create()
+ ->in(__DIR__ . '/src')
+ ->in(__DIR__ . '/tests')
+ )
+ // Enable risky rules (recommended as the ruleset includes risky rules)
+ ->setRiskyAllowed(true)
+;
+```
+
+## Development
+
+This package provides several Composer scripts to help with development:
+
+```bash
+# Run PHP-CS-Fixer in dry-run mode with diff output
+composer cs-check
+
+# Run PHP-CS-Fixer to fix code style issues
+composer cs-fix
+
+# Run PHPStan for static analysis
+composer phpstan
+
+# Run Rector in dry-run mode
+composer rector-dry-run
+
+# Run Rector and apply changes
+composer rector
+
+# Run PHPUnit tests
+composer test
+
+# Run all checks (cs-check, phpstan, rector-dry-run, test)
+composer check
+```
diff --git a/composer.json b/composer.json
index 8d569f4..6695adb 100644
--- a/composer.json
+++ b/composer.json
@@ -3,12 +3,46 @@
"description": "Provides a standard php-cs-fixer configuration used in projects built by Valantic.",
"license": "MIT",
"require": {
- "php": "^8.0",
- "friendsofphp/php-cs-fixer": "^3.16"
+ "php": "^8.1",
+ "friendsofphp/php-cs-fixer": "^3.76"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^12.2.6",
+ "phpstan/phpstan": "^2.1.17",
+ "phpstan/phpstan-deprecation-rules": "^2.0.3",
+ "phpstan/phpstan-strict-rules": "^2.0.4",
+ "rector/rector": "^2.1",
+ "roave/security-advisories": "dev-latest",
+ "phpstan/extension-installer": "^1.4.3"
},
"autoload": {
"psr-4": {
"Valantic\\PhpCsFixerConfig\\": "src"
}
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Valantic\\PhpCsFixerConfig\\Tests\\": "tests"
+ }
+ },
+ "scripts": {
+ "cs-check": "php-cs-fixer fix --dry-run --diff",
+ "cs-fix": "php-cs-fixer fix",
+ "phpstan": "phpstan analyse",
+ "test": "phpunit",
+ "rector": "rector process",
+ "rector-dry-run": "rector process --dry-run",
+ "check": [
+ "@cs-check",
+ "@phpstan",
+ "@rector-dry-run",
+ "@test"
+ ],
+ "post-update-cmd": "composer bump -D"
+ },
+ "config": {
+ "allow-plugins": {
+ "phpstan/extension-installer": true
+ }
}
}
diff --git a/phpstan.neon b/phpstan.neon
new file mode 100644
index 0000000..65dcb04
--- /dev/null
+++ b/phpstan.neon
@@ -0,0 +1,10 @@
+parameters:
+ level: 8
+ paths:
+ - src
+ - tests
+ excludePaths:
+ - vendor
+ tmpDir: .phpstan-cache
+ strictRules:
+ dynamicCallOnStaticMethod: false
diff --git a/phpunit.xml b/phpunit.xml
new file mode 100644
index 0000000..49f3705
--- /dev/null
+++ b/phpunit.xml
@@ -0,0 +1,17 @@
+
+
+
+
+ tests/Unit
+
+
+
+
+ src
+
+
+
diff --git a/rector.php b/rector.php
new file mode 100644
index 0000000..2b2efea
--- /dev/null
+++ b/rector.php
@@ -0,0 +1,24 @@
+withPaths([
+ __DIR__ . '/src',
+ __DIR__ . '/tests',
+ ])
+ ->withPreparedSets(
+ deadCode: true,
+ codeQuality: true,
+ codingStyle: true,
+ typeDeclarations: true,
+ privatization: true,
+ naming: false,
+ instanceOf: true,
+ earlyReturn: true,
+ strictBooleans: true
+ )
+ ->withPhpSets()
+ ->withAttributesSets(symfony: true, phpunit: true);
diff --git a/src/Config.php b/src/Config.php
deleted file mode 100644
index cc1de1f..0000000
--- a/src/Config.php
+++ /dev/null
@@ -1,211 +0,0 @@
- true,
- 'align_multiline_comment' => true,
- 'array_indentation' => true,
- 'array_syntax' => true,
- 'backtick_to_shell_exec' => true,
- 'binary_operator_spaces' => true,
- 'blank_line_before_statement' => [
- 'statements' => [
- 'return',
- ],
- ],
- 'cast_spaces' => true,
- 'class_attributes_separation' => [
- 'elements' => [
- 'method' => 'one',
- ],
- ],
- 'class_definition' => [
- 'single_line' => true,
- ],
- 'class_reference_name_casing' => true,
- 'clean_namespace' => true,
- 'concat_space' => ['spacing' => 'one'],
- 'curly_braces_position' => [
- 'allow_single_line_anonymous_functions' => true,
- 'allow_single_line_empty_anonymous_classes' => true,
- ],
- 'declare_parentheses' => true,
- 'echo_tag_syntax' => true,
- 'empty_loop_body' => ['style' => 'braces'],
- 'empty_loop_condition' => true,
- 'fully_qualified_strict_types' => true,
- 'function_typehint_space' => true,
- 'general_phpdoc_tag_rename' => [
- 'replacements' => [
- 'inheritDocs' => 'inheritDoc',
- ],
- ],
- 'global_namespace_import' => [
- 'import_classes' => false,
- 'import_constants' => false,
- 'import_functions' => false,
- ],
- 'include' => true,
- 'increment_style' => true,
- 'integer_literal_case' => true,
- 'lambda_not_used_import' => true,
- 'linebreak_after_opening_tag' => true,
- 'magic_constant_casing' => true,
- 'magic_method_casing' => true,
- 'method_argument_space' => [
- 'on_multiline' => 'ignore',
- ],
- 'method_chaining_indentation' => true,
- 'multiline_whitespace_before_semicolons' => [
- 'strategy' => 'new_line_for_chained_calls',
- ],
- 'native_function_casing' => true,
- 'native_function_type_declaration_casing' => true,
- 'no_alias_language_construct_call' => true,
- 'no_alternative_syntax' => true,
- 'no_binary_string' => true,
- 'no_blank_lines_after_phpdoc' => true,
- 'no_empty_comment' => true,
- 'no_empty_phpdoc' => true,
- 'no_empty_statement' => true,
- 'no_extra_blank_lines' => [
- 'tokens' => [
- 'attribute',
- 'case',
- 'continue',
- 'curly_brace_block',
- 'default',
- 'extra',
- 'parenthesis_brace_block',
- 'square_brace_block',
- 'switch',
- 'throw',
- 'use',
- ],
- ],
- 'no_leading_namespace_whitespace' => true,
- 'no_mixed_echo_print' => true,
- 'no_multiline_whitespace_around_double_arrow' => true,
- 'no_null_property_initialization' => true,
- 'no_short_bool_cast' => true,
- 'no_singleline_whitespace_before_semicolons' => true,
- 'no_spaces_around_offset' => true,
- 'no_superfluous_phpdoc_tags' => [
- 'allow_mixed' => true,
- 'allow_unused_params' => true,
- ],
- 'no_trailing_comma_in_singleline' => true,
- 'no_unneeded_control_parentheses' => [
- 'statements' => [
- 'break',
- 'clone',
- 'continue',
- 'echo_print',
- 'others',
- 'return',
- 'switch_case',
- 'yield',
- 'yield_from',
- ],
- ],
- 'no_unneeded_curly_braces' => [
- 'namespaces' => true,
- ],
- 'no_unneeded_import_alias' => true,
- 'no_unset_cast' => true,
- 'no_unused_imports' => true,
- 'no_useless_concat_operator' => true,
- 'no_useless_nullsafe_operator' => true,
- 'no_whitespace_before_comma_in_array' => true,
- 'normalize_index_brace' => true,
- 'object_operator_without_whitespace' => true,
- 'operator_linebreak' => [
- 'only_booleans' => true,
- ],
- 'ordered_imports' => [
- 'imports_order' => [
- 'class',
- 'function',
- 'const',
- ],
- 'sort_algorithm' => 'alpha',
- ],
- 'php_unit_fqcn_annotation' => true,
- 'php_unit_method_casing' => true,
- 'phpdoc_align' => [
- 'align' => 'left',
- ],
- 'phpdoc_annotation_without_dot' => true,
- 'phpdoc_indent' => true,
- 'phpdoc_inline_tag_normalizer' => true,
- 'phpdoc_no_access' => true,
- 'phpdoc_no_alias_tag' => true,
- 'phpdoc_no_package' => true,
- 'phpdoc_no_useless_inheritdoc' => true,
- 'phpdoc_order' => [
- 'order' => [
- 'param',
- 'return',
- 'throws',
- ],
- ],
- 'phpdoc_return_self_reference' => true,
- 'phpdoc_scalar' => true,
- 'phpdoc_separation' => true,
- 'phpdoc_single_line_var_spacing' => true,
- 'phpdoc_summary' => true,
- 'phpdoc_tag_type' => [
- 'tags' => [
- 'inheritDoc' => 'inline',
- ],
- ],
- 'phpdoc_to_comment' => true,
- 'phpdoc_trim' => true,
- 'phpdoc_trim_consecutive_blank_line_separation' => true,
- 'phpdoc_types' => true,
- 'phpdoc_types_order' => [
- 'null_adjustment' => 'always_last',
- 'sort_algorithm' => 'none',
- ],
- 'phpdoc_var_without_name' => true,
- 'protected_to_private' => true,
- 'return_assignment' => true,
- 'semicolon_after_instruction' => true,
- 'simple_to_complex_string_variable' => true,
- 'single_class_element_per_statement' => true,
- 'single_import_per_statement' => true,
- 'single_line_comment_spacing' => true,
- 'single_line_comment_style' => [
- 'comment_types' => [
- 'hash',
- ],
- ],
- 'single_line_throw' => true,
- 'single_quote' => true,
- 'single_space_around_construct' => true,
- 'space_after_semicolon' => [
- 'remove_in_empty_for_expressions' => true,
- ],
- 'standardize_increment' => true,
- 'standardize_not_equals' => true,
- 'switch_continue_to_break' => true,
- 'trailing_comma_in_multiline' => [
- 'elements' => ['arguments', 'arrays', 'match', 'parameters'],
- ],
- 'trim_array_spaces' => true,
- 'types_spaces' => true,
- 'unary_operator_spaces' => true,
- 'whitespace_after_comma_in_array' => true,
- 'yoda_style' => [
- 'equal' => false,
- 'identical' => false,
- 'less_and_greater' => false,
- ],
- ];
- }
-}
diff --git a/src/ConfigFactory.php b/src/ConfigFactory.php
new file mode 100644
index 0000000..e9b4434
--- /dev/null
+++ b/src/ConfigFactory.php
@@ -0,0 +1,21 @@
+> $additionalRules
+ */
+ public static function createValanticConfig(array $additionalRules = []): Config
+ {
+ $config = new Config();
+ $config->setRules(array_merge(RuleSet::getValanticRules(), $additionalRules));
+
+ return $config;
+ }
+}
diff --git a/src/RuleSet.php b/src/RuleSet.php
new file mode 100644
index 0000000..a8f70b0
--- /dev/null
+++ b/src/RuleSet.php
@@ -0,0 +1,169 @@
+>
+ */
+ public static function getValanticRules(): array
+ {
+ $rules = [
+ '@PER-CS2.0' => true,
+ '@PER-CS2.0:risky' => true,
+ '@Symfony' => true,
+ '@Symfony:risky' => true,
+ 'array_push' => false,
+ 'native_constant_invocation' => false,
+ 'native_function_invocation' => false,
+ 'no_useless_return' => true,
+ 'self_accessor' => false, // do not enable self_accessor as it breaks pimcore models relying on get_called_class()
+ 'strict_comparison' => true,
+ 'strict_param' => true,
+ 'yoda_style' => [
+ 'equal' => false,
+ 'identical' => false,
+ 'less_and_greater' => false,
+ ],
+ 'blank_line_before_statement' => [
+ 'statements' => [
+ 'break',
+ 'case',
+ 'continue',
+ 'declare',
+ 'default',
+ 'do',
+ 'exit',
+ 'for',
+ 'foreach',
+ 'goto',
+ 'if',
+ 'include',
+ 'include_once',
+ // 'phpdoc',
+ 'require',
+ 'require_once',
+ 'return',
+ 'switch',
+ 'throw',
+ 'try',
+ 'while',
+ 'yield',
+ 'yield_from',
+ ],
+ ],
+ 'concat_space' => ['spacing' => 'one'],
+ 'declare_strict_types' => true,
+ 'increment_style' => [
+ 'style' => 'post',
+ ],
+ 'method_argument_space' => [
+ 'attribute_placement' => 'standalone',
+ 'on_multiline' => 'ensure_fully_multiline',
+ ],
+ 'method_chaining_indentation' => true,
+ 'multiline_comment_opening_closing' => true,
+ 'multiline_whitespace_before_semicolons' => ['strategy' => 'new_line_for_chained_calls'],
+ 'no_superfluous_phpdoc_tags' => ['allow_hidden_params' => false, 'remove_inheritdoc' => true],
+ 'no_unset_on_property' => true,
+ 'no_useless_else' => true,
+ 'ordered_class_elements' => [
+ 'order' => [
+ 'use_trait',
+ 'case',
+ 'constant',
+ 'constant_public',
+ 'constant_protected',
+ 'constant_private',
+ 'property',
+ 'property_public_abstract',
+ 'property_protected_abstract',
+ 'property_static',
+ 'property_public_static',
+ 'property_protected_static',
+ 'property_private_static',
+ 'property_public',
+ 'property_protected',
+ 'property_private',
+ 'construct',
+ 'destruct',
+ 'magic',
+ 'phpunit',
+ 'method',
+ 'method_abstract',
+ 'method_public_abstract',
+ 'method_public_abstract_static',
+ 'method_protected_abstract',
+ 'method_protected_abstract_static',
+ 'method_private_abstract',
+ 'method_private_abstract_static',
+ 'method_static',
+ 'method_public_static',
+ 'method_protected_static',
+ 'method_private_static',
+ 'method_public',
+ 'method_protected',
+ 'method_private',
+ ],
+ ],
+ 'phpdoc_align' => ['align' => 'left', 'spacing' => 1],
+ 'phpdoc_to_comment' => true,
+ 'phpdoc_annotation_without_dot' => false,
+ 'ordered_imports' => [
+ 'imports_order' => ['class', 'function', 'const'],
+ 'sort_algorithm' => 'alpha',
+ ],
+ 'regular_callable_call' => true,
+ 'return_assignment' => true,
+ 'single_line_throw' => false,
+ 'trailing_comma_in_multiline' => [
+ 'after_heredoc' => true,
+ 'elements' => ['arguments', 'array_destructuring', 'arrays', 'match', 'parameters'],
+ ],
+ ];
+
+ return self::addPhpVersionSpecificRules($rules);
+ }
+
+ private static function getCurrentPhpVersion(): string
+ {
+ return PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION;
+ }
+
+ /**
+ * @param array> $rules
+ *
+ * @return array>
+ */
+ private static function addPhpVersionSpecificRules(array $rules): array
+ {
+ $phpVersion = self::getCurrentPhpVersion();
+
+ $version = (int) str_replace('.', '', $phpVersion);
+
+ $availableRuleSets = \PhpCsFixer\RuleSet\RuleSets::getSetDefinitionNames();
+
+ for ($majorMinor = 80; $majorMinor <= 99; $majorMinor++) {
+ if ($majorMinor > $version) {
+ break;
+ }
+
+ $migrationSet = sprintf('@PHP%dMigration', $majorMinor);
+
+ if (in_array($migrationSet, $availableRuleSets, true)) {
+ $rules[$migrationSet] = true;
+ }
+
+ $riskyMigrationSet = sprintf('%s:risky', $migrationSet);
+
+ if (in_array($riskyMigrationSet, $availableRuleSets, true)) {
+ $rules[$riskyMigrationSet] = true;
+ }
+ }
+
+ return $rules;
+ }
+}
diff --git a/tests/Unit/PhpCsFixerConfigTest.php b/tests/Unit/PhpCsFixerConfigTest.php
new file mode 100644
index 0000000..0567a1f
--- /dev/null
+++ b/tests/Unit/PhpCsFixerConfigTest.php
@@ -0,0 +1,91 @@
+assertNotEmpty($rules);
+
+ $this->assertArrayHasKey('@PER-CS2.0', $rules);
+ $this->assertArrayHasKey('@PER-CS2.0:risky', $rules);
+ $this->assertArrayHasKey('@Symfony', $rules);
+ $this->assertArrayHasKey('@Symfony:risky', $rules);
+ $this->assertArrayHasKey('array_push', $rules);
+ $this->assertArrayHasKey('yoda_style', $rules);
+
+ // Check that PHP version specific rules are included
+ $phpVersion = PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION;
+ $version = (int) str_replace('.', '', $phpVersion);
+
+ if ($version >= 80) {
+ $this->assertArrayHasKey('@PHP80Migration', $rules);
+
+ // Check if the risky rule set exists
+ $availableRuleSets = RuleSets::getSetDefinitionNames();
+
+ if (in_array('@PHP80Migration:risky', $availableRuleSets, true)) {
+ $this->assertArrayHasKey('@PHP80Migration:risky', $rules);
+ }
+ }
+
+ if ($version >= 81) {
+ $this->assertArrayHasKey('@PHP81Migration', $rules);
+ }
+ }
+
+ /**
+ * Test that createValanticConfig() returns a Config object with the basic ruleset.
+ */
+ public function testCreateValanticConfig(): void
+ {
+ $config = ConfigFactory::createValanticConfig();
+
+ $this->assertInstanceOf(Config::class, $config);
+
+ $rules = $config->getRules();
+ $this->assertNotEmpty($rules);
+
+ // Check that basic rules are included
+ $this->assertArrayHasKey('@PER-CS2.0', $rules);
+ $this->assertArrayHasKey('@PER-CS2.0:risky', $rules);
+ $this->assertArrayHasKey('@Symfony', $rules);
+ $this->assertArrayHasKey('@Symfony:risky', $rules);
+
+ // Check that risky is not allowed by default
+ $this->assertFalse($config->getRiskyAllowed());
+ }
+
+ /**
+ * Test that createValanticConfig() with additional rules merges them correctly.
+ */
+ public function testCreateValanticConfigWithAdditionalRules(): void
+ {
+ $additionalRules = [
+ 'array_syntax' => ['syntax' => 'short'],
+ 'custom_rule' => true,
+ ];
+
+ $config = ConfigFactory::createValanticConfig($additionalRules);
+
+ $rules = $config->getRules();
+ $this->assertArrayHasKey('array_syntax', $rules);
+ $this->assertArrayHasKey('custom_rule', $rules);
+ $this->assertEquals(['syntax' => 'short'], $rules['array_syntax']);
+ $this->assertTrue($rules['custom_rule']);
+ }
+}