mrpunyapal/rector-pest
Rector rules for migrating PHP tests to Pest. Automates converting PHPUnit-style tests and assertions into Pest’s fluent syntax, helping you modernize test suites quickly and consistently with minimal manual edits.
Rector Pest now has two layers:
The semantic layer is intentionally analyzer-agnostic. Rector Pest does not need PestStan at runtime to classify issues, resolve identifiers, or map safe fixes for package consumers. This repository still uses PestStan as a development-only PHPStan extension, which is separate from the runtime interoperability contract exposed by Rector Pest itself.
The canonical registry lives in src/Registry/PestSemanticIssues.php and defines:
Every semantic rule extends AbstractSemanticPestRector, which exposes the registry metadata without re-encoding it inside each Rector rule.
SemanticIssueMapper resolves the canonical issue to one or more safe Rector rules.That flow keeps analysis and remediation separate. An analyzer can say that a matcher is redundant, impossible, or unsupported without directly deciding how a fix should be applied.
PestChainAnalyzer provides lightweight chain-shape helpers.HookSemanticAnalyzer finds invalid hook placement inside describe() blocks.SemanticExpectationAnalyzer classifies deterministic literal type checks using factual output such as matcher category, literal category, negation, and match result.PestSemanticIssue is the immutable metadata contract.PestDiagnosticResolver canonicalizes external diagnostic identifiers.SemanticFixCandidate is the DTO for a potential safe fix.SemanticIssueMapper maps canonical issues to semantic Rector rules.Current auto-fixes intentionally stay narrow:
beforeAll() and afterAll() inside describe() with per-test hooksrepeat() counts to 1Modeled-but-not-auto-fixed issues remain part of the registry so future tooling can surface review hints without forcing unsafe rewrites.
The semantic layer avoids becoming a second full static analyzer.
and() and json() block redundant-cleanup rewrites$thisThe package is ready to consume diagnostics from external tools through canonical identifiers instead of direct runtime coupling.
This makes it possible to share diagnostics across Rector Pest, PestStan, editor tooling, and future ecosystem packages without duplicating transformation logic.
How can I help you explore Laravel packages today?