ergebnis/rector-rules
Custom Rector rules from Ergebnis to standardize and modernize PHP code. Includes sorting associative arrays and match arms, converting Faker generator property fetches to method calls, and fixing namespaced symbol references. Install via Composer for dev.
Installation:
composer require --dev ergebnis/rector-rules
Configure Rector in rector.php:
use Ergebnis\Rector\Rules\Sets\ErgebnisRules;
return [
ErgebnisRules::set(),
// Other Rector rules...
];
Run Rector:
vendor/bin/rector process src
Apply the new ReplaceTestAttributeWithTestPrefixRector to migrate legacy PHPUnit test classes from annotations to attributes:
vendor/bin/rector process tests --rule "Ergebnis\Rector\Rules\PHPUnit\ReplaceTestAttributeWithTestPrefixRector"
CI/CD Pipeline (updated for new rule):
# .github/workflows/rector.yml
jobs:
rector:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: composer require --dev ergebnis/rector-rules
- run: vendor/bin/rector process tests --dry-run --parallel --rule "Ergebnis\Rector\Rules\PHPUnit\ReplaceTestAttributeWithTestPrefixRector"
Pre-commit Hook (with PHPUnit focus):
return [
ErgebnisRules::set(),
'autoload_paths' => [__DIR__ . '/tests'],
'parallel' => true,
'cache_directories' => [__DIR__ . '/var/rector'],
'exclude_paths' => ['src/'], // Focus on tests
];
PHPUnit Attribute Migration:
// rector.php
return [
ErgebnisRules::set(),
'rules' => [
PHPUnit\ReplaceTestAttributeWithTestPrefixRector::class => [
'prefix' => 'test_', // Default prefix for test methods
'skip' => [
'Feature\\LegacyAnnotationsTest', // Exclude specific classes
],
],
],
];
Combined Test Modernization:
vendor/bin/rector process tests --rule "Ergebnis\Rector\Rules\PHPUnit\ReplaceTestAttributeWithTestPrefixRector" --rule "Ergebnis\Rector\Rules\Faker\GeneratorPropertyFetchToMethodCallRector"
Selective Test Migration:
vendor/bin/rector process tests/Unit --rule "Ergebnis\Rector\Rules\PHPUnit\ReplaceTestAttributeWithTestPrefixRector" --dry-run
PHPUnit Attribute Rule Limitations:
ReplaceTestAttributeWithTestPrefixRector only handles method names prefixed with @test (e.g., @testLogin). Explicit annotations like @test("login") are ignored.--dry-run first to identify unsupported cases, then manually refactor or extend the rule.Namespace Collisions in Tests:
ReferenceNamespacedSymbolsRelativeToNamespacePrefixRector with PHPUnit rules may cause conflicts in test namespaces.'exclude_paths' => ['tests/'],
Test Prefix Conflicts:
test_ prefix may conflict with existing method names (e.g., testLogin vs testLoginUser).'rules' => [
ReplaceTestAttributeWithTestPrefixRector::class => [
'prefix' => 'should_', // Alternative prefix
],
],
Legacy Test Structure:
setUpBeforeClass or tearDownAfterClass may break if method names are modified.Dry Run with PHPUnit Focus:
vendor/bin/rector process tests --dry-run --rule "Ergebnis\Rector\Rules\PHPUnit\ReplaceTestAttributeWithTestPrefixRector" -vv
Rule-Specific Logging:
// rector.php
return [
'logging' => true,
'rules' => [
PHPUnit\ReplaceTestAttributeWithTestPrefixRector::class => [
'logging' => true,
'prefix' => 'test_',
],
],
];
Partial Test Suite Migration:
vendor/bin/rector process tests/Unit/ --rule "Ergebnis\Rector\Rules\PHPUnit\ReplaceTestAttributeWithTestPrefixRector"
Custom Test Prefix Logic:
use Ergebnis\Rector\Rules\PHPUnit\ReplaceTestAttributeWithTestPrefixRector;
class CustomTestPrefixRector extends ReplaceTestAttributeWithTestPrefixRector {
public function getPrefix(): string {
return 'should_' . $this->getMethodName(); // Dynamic prefix
}
}
Attribute-to-Annotation Hybrid:
'rules' => [
PHPUnit\ReplaceTestAttributeWithTestPrefixRector::class => [
'prefix' => 'test_',
],
PHPUnit\ReplaceAnnotationWithAttributeRector::class => [
'skip' => ['@test'], // Skip already migrated methods
],
],
Integration with Pest:
vendor/bin/rector process tests/Pest --rule "Ergebnis\Rector\Rules\PHPUnit\ReplaceTestAttributeWithTestPrefixRector"
Default Prefix Behavior:
test_ prefix. Omit the configuration to use the default.Case Sensitivity:
strtolower in custom extensions for case-insensitive logic.Method Name Validation:
@test. Use --dry-run to audit unsupported cases.Targeted Test Processing:
vendor/bin/rector process tests/Unit --parallel --workers 2 --rule "Ergebnis\Rector\Rules\PHPUnit\ReplaceTestAttributeWithTestPrefixRector"
Cache Optimization:
return [
'cache_directories' => [__DIR__ . '/var/rector'],
'autoload_paths' => [__DIR__ . '/tests'],
];
Exclude Non-Relevant Tests:
return [
'exclude_paths' => [
'tests/Integration/', // Exclude slower tests
],
];
How can I help you explore Laravel packages today?