8000 Custom mutator generator by maks-rafalko · Pull Request #1969 · infection/infection · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Custom mutator generator #1969

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
May 27, 2024
Merged

Custom mutator generator #1969

merged 25 commits into from
May 27, 2024

Conversation

maks-rafalko
Copy link
Member
@maks-rafalko maks-rafalko commented May 20, 2024

This is a follow up for #1686, docs: infection/site#262

Short description

This PR adds new CLI command to generate custom mutator in a target project, as well as a test for convenient development / testing of brand new mutators.

Details

A lot of things needs to be explained here. After hours of thinking / experimenting how it should be, I came up with this solution that helps developers to generate a "skeleton" of new mutator and a test to for convenient development.

Things to note:

This PR adds a couple of things:

  1. adds bin/infection make:mutator CLI command to generate skeleton for new custom mutator - mutator itself and test file
  2. moves BaseMutatorTestCase.php (and other related classes) to src from tests, so that developers can test their mutators in "Infection runtime". By this, I mean that developers will not blindly create new mutator class, but they will mutate the code in tests and see which mutants (new versions of the source code) are produced. Exactly the same as we do it in out unit tests

bin/infection make:mutator

This idea is taken from Rector's custom-rule command, see https://getrector.com/documentation/custom-rule (implementation).

What it does is basically generates 2 files - mutator and test for it. See __Name__.php and __Name__Test.php files in the diff to understand how it works. __Name__ is replaced with the real name of the new mutator during creation of the files.

Moving BaseMutatorTestCase.php from tests to src - why?

This is needed to allow users to write the following tests:

public static function mutationsProvider(): iterable
{
yield 'It mutates normal plus' => [
<<<'PHP'
<?php
$a = 10 + 3;
PHP
,
<<<'PHP'
<?php
$a = 10 - 3;
PHP
,
];

But to achieve it, we need to do really a lot of things:

Without our base class provided for the end developers, it will be very difficult to write all of this logic themselves. So we basically say for them: "look here, we have Infection runtime which you can use to test your new custom mutator - if you want - you can use it."

In order to use "Infection runtime" in custom mutator's tests, developers will need to require infection/infection. You can ask: "wait, but we extracted infection/mutator exactly to not depend on infection/infection?". And this is still the case!

The project that will implement a custom mutator still needs to depend on infection/mutator in require section. But if they want to use our custom-mutator CLI generator and our base test class, they can require infection/infection to the require-dev section. From dependencies POV, they still depend only on infection/mutator and infection/infection is a dev dependency only for test. So no problem here.

Actually, Rector does the same thing. They have their base test class in src and package it with the source code:

I've already created documentation for writing Custom Mutators - infection/site#261 - and after this PR it will be greatly simplified from developer's point of view, improving DX. Docs PR supporting this change: infection/site#262

Example of usage:

image

Generated files:

image

@theofidry
Copy link
Member

spend the day in some docker shit, will wait tomorrow / after tomorrow for a review 😅

@sanmai sanmai self-requested a review May 24, 2024 15:25
@maks-rafalko
Copy link
Member Author
maks-rafalko commented May 24, 2024

ping @theofidry @sanmai

it would be nice if you can do review, cause I'm going to move forward. Basically, everything is done to go live (from my tests and understanding)

@maks-rafalko maks-rafalko force-pushed the feature/custom-rule-generator branch from bb67c37 to 0e2d370 Compare May 24, 2024 22:03
@maks-rafalko
Copy link
Member Author

It would be also nice if you can go through the docs and try to do it yourself :) just to check if it's clear for you what to do

Copy link
Member
@theofidry theofidry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had a brief look, couldn't get to try it or check it out locally. It's actually a lot less changes than I expected (from the diff)

@@ -189,7 +195,7 @@ private function assertSyntaxIsValid(string $realMutatedCode): void
$returnCode,
sprintf(
'Mutator %s produces invalid code',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'Mutator %s produces invalid code',
'The mutator "%s" produced invalid PHP code.',

Might be worth tweaking it to print for which output this is the case?

@maks-rafalko
Copy link
Member Author

@theofidry please review again

@maks-rafalko
Copy link
Member Author

New thing: https://infection-php.dev/ast - this will help custom mutator developers to better/easier understand what to use in Mutator::canMutate(). The code is clickable after submitting

@maks-rafalko
Copy link
Member Author

thank you @theofidry and @sidz

@sanmai feel free to add comments, will address in separate PR

@maks-rafalko maks-rafalko merged commit 0b13941 into master May 27, 2024
55 checks passed
@maks-rafalko maks-rafalko deleted the feature/custom-rule-generator branch May 27, 2024 23:01
github-merge-queue bot referenced this pull request in Lendable/json-serializer May 28, 2024
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [infection/infection](https://togithub.com/infection/infection) |
`^0.28.1` -> `^0.29.0` |
[![age](https://developer.mend.io/api/mc/badges/age/packagist/infection%2finfection/0.29.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/packagist/infection%2finfection/0.29.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/packagist/infection%2finfection/0.28.1/0.29.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/packagist/infection%2finfection/0.28.1/0.29.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>infection/infection (infection/infection)</summary>

###
[`v0.29.0`](https://togithub.com/infection/infection/blob/HEAD/CHANGELOG.md#0290-2024-05-28)

[Compare
Source](https://togithub.com/infection/infection/compare/0.28.1...0.29.0)

[Full
Changelog](https://togithub.com/infection/infection/compare/0.28.1...0.29.0)

**Added:**

- Support custom mutators by
[@&#8203;vss414](https://togithub.com/vss414) in
[https://github.com/infection/infection/pull/1686](https://togithub.com/infection/infection/pull/1686)
- Custom mutator generator by
[@&#8203;maks-rafalko](https://togithub.com/maks-rafalko) in
[https://github.com/infection/infection/pull/1969](https://togithub.com/infection/infection/pull/1969)

Read about how to create custom mutators:
https://infection.github.io/guide/custom-mutators.html

**Changed:**

- Move `Infection\Mutator\Mutator` to a separate package by
[@&#8203;maks-rafalko](https://togithub.com/maks-rafalko) in
[https://github.com/infection/infection/pull/1963](https://togithub.com/infection/infection/pull/1963)
- Make `Mutator::getDefinition` return type non-nullable by
[@&#8203;maks-rafalko](https://togithub.com/maks-rafalko) in
[https://github.com/infection/infection/pull/1958](https://togithub.com/infection/infection/pull/1958)
- Enable Rector's `AddCoversClassAttributeRector` rule by
[@&#8203;maks-rafalko](https://togithub.com/maks-rafalko) in
[https://github.com/infection/infection/pull/1962](https://togithub.com/infection/infection/pull/1962)
- Mention Discord instead of Slack in issue github template by
[@&#8203;staabm](https://togithub.com/staabm) in
[https://github.com/infection/infection/pull/1951](https://togithub.com/infection/infection/pull/1951)
- test: Force mutators to include remedies by
[@&#8203;theofidry](https://togithub.com/theofidry) in
[https://github.com/infection/infection/pull/1954](https://togithub.com/infection/infection/pull/1954)
- Use the latest composer 2 to prevent issue with incompatibility for
Box and composer 2.1 by
[@&#8203;maks-rafalko](https://togithub.com/maks-rafalko) in
[https://github.com/infection/infection/pull/1957](https://togithub.com/infection/infection/pull/1957)
- Use the latest v1 test checker action by
[@&#8203;maks-rafalko](https://togithub.com/maks-rafalko) in
[https://github.com/infection/infection/pull/1960](https://togithub.com/infection/infection/pull/1960)
- Upgrade Rector and fix new issues by
[@&#8203;maks-rafalko](https://togithub.com/maks-rafalko) in
[https://github.com/infection/infection/pull/1961](https://togithub.com/infection/infection/pull/1961)
- Use new PHP-CS-Fixer with parallelization by
[@&#8203;maks-rafalko](https://togithub.com/maks-rafalko) in
[https://github.com/infection/infection/pull/1964](https://togithub.com/infection/infection/pull/1964)
- Remove our own custom FQCN visitor as we already use php-parser's
`NameResolver` visitor by
[@&#8203;maks-rafalko](https://togithub.com/maks-rafalko) in
[https://github.com/infection/infection/pull/1967](https://togithub.com/infection/infection/pull/1967)
- Replace deprecated constant
`NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN` with
`NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN` by
[@&#8203;maks-rafalko](https://togithub.com/maks-rafalko) in
[https://github.com/infection/infection/pull/1968](https://togithub.com/infection/infection/pull/1968)
- Remove our own `ParentConnectorVisitor` and use `nikic-phpparser`'s
one by [@&#8203;maks-rafalko](https://togithub.com/maks-rafalko) in
[https://github.com/infection/infection/pull/1970](https://togithub.com/infection/infection/pull/1970)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/Lendable/json-serializer).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4zNzcuOCIsInVwZGF0ZWRJblZlciI6IjM3LjM3Ny44IiwidGFyZ2V0QnJhbmNoIjoibWFzdGVyIiwibGFiZWxzIjpbXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DX Developer Experience
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
0