diff --git a/docs/how_to_add_test_for_rector_rule.md b/docs/how_to_add_test_for_rector_rule.md new file mode 100644 index 00000000000..f3ae3c28fb6 --- /dev/null +++ b/docs/how_to_add_test_for_rector_rule.md @@ -0,0 +1,125 @@ +# How to Add Test for Rector Rule + +## 1. Detect the Rector Rule + +Run Rector only on 1 directory, or better 1 file. + +```bash +vendor/bin/rector process compiler/src/PhpScoper/StaticEasyPrefixer.php +``` + +See "Applied rules" under the diff: + +![Applied Rules](/docs/images/docs_applied_rules.png) + +Our rule in this example is: `Rector\SOLID\Rector\Class_\FinalizeClassesWithoutChildrenRector` + +This rule's job is to add `final` to every class that has no children and is not a Doctrine entity = everywhere it can without breaking our code. + +## 2. Detect the Minimal File + +Usually, the Rector diff output is long and contains many other errors related to other rules. It's a mess; we can't use that for a test fixture. We need to find **1 responsible line**. + +The best way is to copy the file to local code, e.g. `app/SomeFile.php` a put only the broken line there. + +In our case, all we need is: + +```php +class StaticEasyPrefixer +{ +} +``` + +Then rerun Rector to confirm: + +```bash +vendor/bin/rector process app/SomeFile.php +``` + +Do we have the same diff? Great! + +## 3. Find the Rector Test Case + +Now we need to find the test case. The test case name is rule + `Test` suffix. + +`FinalizeClassesWithoutChildrenRector` + +↓ + +`FinalizeClassesWithoutChildrenRectorTest` (test class) + +↓ + +`FinalizeClassesWithoutChildrenRectorTest.php` (test file) + +Right here: + +![Rule Test Case](/docs/images/docs_rule_test_case.png) + +## 4. Add Change or No-Change Test Fixture File + +Next to the test case, there is `/Fixture` directory. It contains many test fixture files that verified the Rector rule work correctly in all possible cases. + +Do you see *test fixture file* first time? It's a file with real-life PHP code that test 1 specific case that rule should cover or avoid. E.g., one test fixture file can contain a Doctrine entity that cannot be final and should be skipped by this rule. By convention, the first fixture file has the name `fixture.php.inc`. + +In the `/Fixture` directory, we create our test fixture file, e.g., `add_final.php.inc`. The `.php.inc` is there on purpose, so the file is hidden from coding standard tools and static analysis. + +There are 2 fixture formats. + +### 1. The Code Should Change + +```bash + +----- + +``` + +### 2. The Code Should Be Skipped + +```bash + +``` + +
+ +In this particular case, the code should change - `final` should be added so that the test fixture would look like this: + +```php + +----- + +``` + +- The closing `?>` is there for slightly better PHPStorm. +- The PSR-4 namespace is there to make each class unique because the test classes are loaded to an analysis by reflection and must be unique +- The file name conventions => class is `add_final.php.inc` => `AddFinal` class + +Run PHPUnit with the test file to confirm: + +```bash +vendor/bin/phpunit rules/solid/tests/Rector/Class_/FinalizeClassesWithoutChildrenRector/FinalizeClassesWithoutChildrenRectorTest.php +``` + +To run only the single test fixture, add `--filter test#X`, where X is the fixture's order number. + +```bash +vendor/bin/phpunit rules/solid/tests/Rector/Class_/FinalizeClassesWithoutChildrenRector/FinalizeClassesWithoutChildrenRectorTest.php --filter test#4 +``` + +If PHPUnit fails, you've successfully added a test case! :) diff --git a/docs/images/docs_applied_rules.png b/docs/images/docs_applied_rules.png new file mode 100644 index 00000000000..d7dfaf0821c Binary files /dev/null and b/docs/images/docs_applied_rules.png differ diff --git a/docs/images/docs_rule_test_case.png b/docs/images/docs_rule_test_case.png new file mode 100644 index 00000000000..f6d806584be Binary files /dev/null and b/docs/images/docs_rule_test_case.png differ