рд▓реЗрдЦрди рдкрд░реАрдХреНрд╖рдг рдХреЛ рдХреЛрдб рдХреЗ рд╕рд╣реА рд╕рдВрдЪрд╛рд▓рди рдореЗрдВ рдЖрддреНрдорд╡рд┐рд╢реНрд╡рд╛рд╕ рдХреЛ рдкреНрд░реЗрд░рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЕрдХреНрд╕рд░ рд╣рдо рдХреЛрдб рдХреЗ рдХрд╡рд░реЗрдЬ рдХреА рдбрд┐рдЧреНрд░реА рдкрд░ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЬрдм рд╣рдо 100% рддрдХ рдкрд╣реБрдВрдЪрддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╕рдорд╛рдзрд╛рди рд╕рд╣реА рд╣реИред рдХреНрдпрд╛ рдЖрдк рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдирд┐рд╢реНрдЪрд┐рдд рд╣реИрдВ? рд╢рд╛рдпрдж рдПрдХ рдЙрдкрдХрд░рдг рд╣реИ рдЬреЛ рдЕрдзрд┐рдХ рд╕рдЯреАрдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрдЧрд╛?
рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди рдкрд░реАрдХреНрд╖рдг
рдпрд╣ рд╢рдмреНрдж рдПрдХ рдРрд╕реА рд╕реНрдерд┐рддрд┐ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рд╣рдо рдХреЛрдб рдХреЗ рдЫреЛрдЯреЗ рдЯреБрдХрдбрд╝реЛрдВ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдХреИрд╕реЗ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддрд╛ рд╣реИред рдпрджрд┐, рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рдмрд╛рдж, рдкрд░реАрдХреНрд╖рдг рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХреЛрдб рдХреЗ рдЗрди рдЯреБрдХрдбрд╝реЛрдВ рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИрдВред рдмреЗрд╢рдХ, рдпрд╣ рд╕рдм рдЗрд╕ рдмрд╛рдд рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд╣рдо рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреНрдпрд╛ рдмрджрд▓ рд░рд╣реЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдореЗрдВ рд╕рднреА рд╕рдмрд╕реЗ рдЫреЛрдЯреЗ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрдВрдбреЗрдВрдЯ рдпрд╛ рдЪрд░ рдирд╛рдо, рдХреНрдпреЛрдВрдХрд┐ рдЙрдирдХреЗ рдмрд╛рдж рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рднреА рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдкреВрд░рд╛ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЗрд╕рд▓рд┐рдП, рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ, рд╣рдо рддрдерд╛рдХрдерд┐рдд рдореНрдпреВрдЯреЗрдЯрд░ (рд╕рдВрд╢реЛрдзрдХ рд╡рд┐рдзрд┐рдпреЛрдВ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рдПрдХ рдХреЛрдб рдХреЛ рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рдмрджрд▓ рджреЗрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рддрд░рд╣ рд╕реЗ рдЬреЛ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИред рд╣рдо рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдиреАрдЪреЗ рдФрд░ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗред рдХрднреА-рдХрднреА рд╣рдо рдЦреБрдж рдРрд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХрд░рддреЗ рд╣реИрдВ, рдЕрдЧрд░ рд╣рдо рдХреЛрдб рдореЗрдВ рдХреБрдЫ рдмрджрд▓рддреЗ рд╣реИрдВ рддреЛ рдЬрд╛рдБрдЪ рдЯреВрдЯ рдЬрд╛рддреА рд╣реИред рдпрджрд┐ рд╣рдордиреЗ "рдЖрдзрд╛ рд╕рд┐рд╕реНрдЯрдо" рдХреЛ рд░рд┐рдлреИрдХреНрдЯ рдХрд┐рдпрд╛ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдЕрднреА рднреА рд╣рд░реЗ рд╣реИрдВ, рддреЛ рд╣рдо рддреБрд░рдВрдд рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╡реЗ рдЦрд░рд╛рдм рд╣реИрдВред рдФрд░ рдЕрдЧрд░ рдХрд┐рд╕реА рдиреЗ рдРрд╕рд╛ рдХрд┐рдпрд╛ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдЕрдЪреНрдЫреЗ рдереЗ, рддреЛ рдмрдзрд╛рдИ!
рд╕рдВрдХреНрд░рд╛рдордХ рдлреНрд░реЗрдорд╡рд░реНрдХ
рдЖрдЬ PHP рдореЗрдВ, рд╕рдмрд╕реЗ рд▓реЛрдХрдкреНрд░рд┐рдп рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди рдкрд░реАрдХреНрд╖рдг рдврд╛рдВрдЪрд╛ 
рд╕рдВрдХреНрд░рдордг рд╣реИ ред рдпрд╣ PHPUnit рдФрд░ PHPSpec рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП PHP 7.1+ рдФрд░ Xdebug рдпрд╛ phpdbg рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
рдкрд╣рд▓рд╛ рд▓реЙрдиреНрдЪ рдФрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди
рдкрд╣рд▓реА рд╢реБрд░реБрдЖрдд рдореЗрдВ, рд╣рдо рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рдЗрдВрдЯрд░реИрдХреНрдЯрд┐рд╡ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ, рдЬреЛ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЗ рд╕рд╛рде рдПрдХ рд╡рд┐рд╢реЗрд╖ рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рддрд╛ рд╣реИ - рд╕рдВрдХреНрд░рдордгред json.distред рдпрд╣ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
{ "timeout": 10, "source": { "directories": [ "src" }, "logs": { "text": "infection.log", "perMutator": "per-mutator.md" }, "mutators": { "@default": true } 
Timeout - рдПрдХ рд╡рд┐рдХрд▓реНрдк рдЬрд┐рд╕рдХрд╛ рдореВрд▓реНрдп рдПрдХ рдкрд░реАрдХреНрд╖рдг рдХреА рдЕрдзрд┐рдХрддрдо рдЕрд╡рдзрд┐ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред 
source рд╣рдо рдЙрди рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рдирд╕реЗ рд╣рдо рдХреЛрдб рдХреЛ рдореНрдпреВрдЯ рдХрд░реЗрдВрдЧреЗ, рдЖрдк рдЕрдкрд╡рд╛рдж рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред 
logs рдореЗрдВ рдПрдХ 
text рд╡рд┐рдХрд▓реНрдк рд╣реЛрддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рд╣рдо рдХреЗрд╡рд▓ рдЧрд▓рдд рдкрд░реАрдХреНрд╖рдгреЛрдВ рдкрд░ рдЖрдБрдХрдбрд╝реЗ рдПрдХрддреНрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИред 
perMutator рд╡рд┐рдХрд▓реНрдк рдЖрдкрдХреЛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдП рдЧрдП 
perMutator рдХреЛ рдмрдЪрд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдФрд░ рдкрдврд╝реЗрдВред
рдЙрджрд╛рд╣рд░рдг
 final class Calculator { public function add(int $a, int $b): int { return $a + $b; } } 
рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЙрдкрд░реЛрдХреНрдд рд╡рд░реНрдЧ рд╣реИред рдЖрдЗрдП PHPUnit рдореЗрдВ рдПрдХ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦреЗрдВ:
 final class CalculatorTest extends TestCase {  private $calculator; public function setUp(): void { $this->calculator = new Calculator(); }  public function testAdd(int $a, int $b, int $expected): void { $this->assertEquals($expected, $this->calculator->add($a, $b)); } public function additionProvider(): array { return [ [0, 0, 0], [6, 4, 10], [-1, -2, -3], [-2, 2, 0] ]; } } 
рдмреЗрд╢рдХ, рдпрд╣ рдкрд░реАрдХреНрд╖рдг 
add() рдкрджреНрдзрддрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд▓рд┐рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЬрдм рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛ 
./vendor/bin/phpunit рд╣рдореЗрдВ рдорд┐рд▓рддрд╛ рд╣реИ:
 PHPUnit 8.2.2 by Sebastian Bergmann and contributors. .... 4 / 4 (100%) Time: 39 ms, Memory: 4.00 MB OK (4 tests, 4 assertions) 
рдЕрдм рдЪрд▓рд╛рдПрдВ 
./vendor/bin/infection :
 You are running Infection with Xdebug enabled. ____ ____ __ _ / _/___ / __/__ _____/ /_(_)___ ____ /  
рд╕рдВрдХреНрд░рдордг рдХреЗ рдЕрдиреБрд╕рд╛рд░, рд╣рдорд╛рд░реЗ рдкрд░реАрдХреНрд╖рдг рд╕рдЯреАрдХ рд╣реИрдВред 
Per-mutator.md рдлрд╝рд╛рдЗрд▓ рдореЗрдВ 
, рд╣рдо рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдореНрдпреВрдЯреЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛:
 
рдореНрдпреВрдЯреЗрдЯрд░ рдкреНрд▓рд╕ рдкреНрд▓рд╕ рд╕реЗ рдорд╛рдЗрдирд╕ рддрдХ рд╕рд╛рдЗрди рдХрд╛ рдПрдХ рд╕рд░рд▓ рдкрд░рд┐рд╡рд░реНрддрди рд╣реИ, рдЬреЛ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рддреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рд┐рдПред рдФрд░ 
PublicVisibility рдЙрддреНрдкрд░рд┐рд╡рд░реНрддреА рдЗрд╕ рдкрджреНрдзрддрд┐ рдХреЗ рдПрдХреНрд╕реЗрд╕ рд╕рдВрд╢реЛрдзрдХ рдХреЛ рдмрджрд▓ рджреЗрддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рднреА рддреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
рдЕрдм рдПрдХ рдФрд░ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред
  public function findGreaterThan(array $numbers, int $threshold): array { return \array_values(\array_filter($numbers, static function (int $number) use ($threshold) { return $number > $threshold; })); }  public function testFindGreaterThan(array $numbers, int $threshold, array $expected): void { $this->assertEquals($expected, $this->calculator->findGreaterThan($numbers, $threshold)); } public function findGreaterThanProvider(): array { return [ [[1, 2, 3], -1, [1, 2, 3]], [[-2, -3, -4], 0, []] ]; } 
рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рдмрд╛рдж, рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрд░рд┐рдгрд╛рдо рджреЗрдЦреЗрдВрдЧреЗ:
 You are running Infection with Xdebug enabled. ____ ____ __ _ / _/___ / __/__ _____/ /_(_)___ ____ /  
рд╣рдорд╛рд░реЗ рдкрд░реАрдХреНрд╖рдг рдареАрдХ рдирд╣реАрдВ рд╣реИрдВред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, infection.log рдлрд╝рд╛рдЗрд▓ рдХреА рдЬрд╛рдБрдЪ рдХрд░реЗрдВ:
 Escaped mutants: ================ 1) /home/sarven/projects/infection-playground/infection-playground/src/Calculator.php:19 [M] UnwrapArrayValues --- Original +++ New @@ @@ */ public function findGreaterThan(array $numbers, int $threshold) : array { - return \array_values(\array_filter($numbers, static function (int $number) use($threshold) { + return \array_filter($numbers, static function (int $number) use($threshold) { return $number > $threshold; - })); + }); } 2) /home/sarven/projects/infection-playground/infection-playground/src/Calculator.php:20 [M] GreaterThan --- Original +++ New @@ @@ public function findGreaterThan(array $numbers, int $threshold) : array { return \array_values(\array_filter($numbers, static function (int $number) use($threshold) { - return $number > $threshold; + return $number >= $threshold; })); } Timed Out mutants: ================== Not Covered mutants: ==================== 
рдкрд╣рд▓реА рдЕрдирд╕реБрд▓рдЭреА рд╕рдорд╕реНрдпрд╛ 
array_values рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣реИред рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЛ рд░реАрд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ 
array_filter рдорд╛рдиреЛрдВ рдХреЛ рдкрд┐рдЫрд▓реА рд╕рд░рдгреА рд╕реЗ рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рд▓реМрдЯрд╛рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдорд╛рд░реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдРрд╕рд╛ рдХреЛрдИ рдорд╛рдорд▓рд╛ рдирд╣реАрдВ рд╣реИ рдЬрдм 
array_values рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рдХреНрдпреЛрдВрдХрд┐ рдЕрдиреНрдпрдерд╛ рдПрдХ рд╣реА рдорд╛рди рдХреЗ рд╕рд╛рде рдПрдХ рд╕рд░рдгреА рд▓реЗрдХрд┐рди рд╡рд┐рднрд┐рдиреНрди рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рджреВрд╕рд░реА рд╕рдорд╕реНрдпрд╛ рд╕реАрдорд╛рд╡рд░реНрддреА рдорд╛рдорд▓реЛрдВ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИред рддреБрд▓рдирд╛ рдореЗрдВ, рд╣рдордиреЗ 
> рд╕рд╛рдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛, рд▓реЗрдХрд┐рди рд╣рдо рдХрд┐рд╕реА рднреА рд╕реАрдорд╛ рдХреЗ рдорд╛рдорд▓реЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП 
>= рд╕рд╛рде рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдЯреВрдЯрддреЗ рд╣реИрдВред рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рдПрдХ рдкрд░реАрдХреНрд╖рдг рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
 public function findGreaterThanProvider(): array { return [ [[1, 2, 3], -1, [1, 2, 3]], [[-2, -3, -4], 0, []], [[4, 5, 6], 4, [5, 6]] ]; } 
рдФрд░ рдЕрдм рд╕рдВрдХреНрд░рдордг рд╕рдм рдХреБрдЫ рд╕реЗ рдЦреБрд╢ рд╣реИ:
 You are running Infection with Xdebug enabled. ____ ____ __ _ / _/___ / __/__ _____/ /_(_)___ ____ /  
Calculator рд╡рд░реНрдЧ рдореЗрдВ рдПрдХ 
subtract рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реЗрдВ, рд▓реЗрдХрд┐рди PHPUnit рдореЗрдВ рдПрдХ рдЕрд▓рдЧ рдкрд░реАрдХреНрд╖рдг рдХреЗ рдмрд┐рдирд╛:
 public function subtract(int $a, int $b): int { return $a - $b; } 
рдФрд░ рдЗрдиреНрдлреЗрдХреНрд╢рди рдЪрд▓рдиреЗ рдХреЗ рдмрд╛рдж рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ:
 You are running Infection with Xdebug enabled. ____ ____ __ _ / _/___ / __/__ _____/ /_(_)___ ____ /  
рдЗрд╕ рдмрд╛рд░, рдЯреВрд▓ рдиреЗ рджреЛ рдЦреБрд▓рд╛ рдореНрдпреВрдЯреЗрд╢рди рд▓реМрдЯрд╛ рджрд┐рдПред
 Escaped mutants: ================ Timed Out mutants: ================== Not Covered mutants: ==================== 1) /home/sarven/projects/infection-playground/infection-playground/src/Calculator.php:24 [M] PublicVisibility --- Original +++ New @@ @@ return $number > $threshold; })); } - public function subtract(int $a, int $b) : int + protected function subtract(int $a, int $b) : int { return $a - $b; } 2) /home/sarven/projects/infection-playground/infection-playground/src/Calculator.php:26 [M] Minus --- Original +++ New @@ @@ public function subtract(int $a, int $b) : int { - return $a - $b; + return $a + $b; } 
рдореИрдЯреНрд░рд┐рдХреНрд╕
рдкреНрд░рддреНрдпреЗрдХ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рдмрд╛рдж, рдЙрдкрдХрд░рдг рддреАрди рдореИрдЯреНрд░рд┐рдХреНрд╕ рд▓реМрдЯрд╛рддрд╛ рд╣реИ:
 Metrics: Mutation Score Indicator (MSI): 47% Mutation Code Coverage: 67% Covered Code MSI: 70% 
Mutation Score Indicator - рдкрд░реАрдХреНрд╖рдгреЛрдВ рджреНрд╡рд╛рд░рд╛ рдкрддрд╛ рдЪрд▓рд╛ рдореНрдпреВрдЯреЗрд╢рди рдХрд╛ рдкреНрд░рддрд┐рд╢рддред
рдореАрдЯреНрд░рд┐рдХ рдХреА рдЧрдгрдирд╛ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рддреА рд╣реИ:
 TotalDefeatedMutants = KilledCount + TimedOutCount + ErrorCount; MSI = (TotalDefeatedMutants / TotalMutantsCount) * 100; 
Mutation Code Coverage - рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди рджреНрд╡рд╛рд░рд╛ рдХрд╡рд░ рдХреЛрдб рдХрд╛ рдЕрдиреБрдкрд╛рддред
рдореАрдЯреНрд░рд┐рдХ рдХреА рдЧрдгрдирд╛ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рддреА рд╣реИ:
 TotalCoveredByTestsMutants = TotalMutantsCount - NotCoveredByTestsCount; CoveredRate = (TotalCoveredByTestsMutants / TotalMutantsCount) * 100; 
Covered Code Mutation Score Indicator - рдкрд░реАрдХреНрд╖рдгреЛрдВ рджреНрд╡рд╛рд░рд╛ рдХрд╡рд░ рдХрд┐рдП рдЧрдП рдХреЛрдб рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреА рдкреНрд░рднрд╛рд╡рд╢реАрд▓рддрд╛ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИред
рдореАрдЯреНрд░рд┐рдХ рдХреА рдЧрдгрдирд╛ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рддреА рд╣реИ:
 TotalCoveredByTestsMutants = TotalMutantsCount - NotCoveredByTestsCount; TotalDefeatedMutants = KilledCount + TimedOutCount + ErrorCount; CoveredCodeMSI = (TotalDefeatedMutants / TotalCoveredByTestsMutants) * 100; 
рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ
рдЙрдкрд░реЛрдХреНрдд рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдХреЗрд╡рд▓ рдПрдХ рд╣реА рд╡рд░реНрдЧ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдордиреЗ рдмрд┐рдирд╛ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рдВрдХреНрд░рдордг рдЪрд▓рд╛рдпрд╛ред рд▓реЗрдХрд┐рди рд╕рд╛рдзрд╛рд░рдг рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдкрд░ рд░реЛрдЬрдорд░реНрд░рд╛ рдХреЗ рдХрд╛рдо рдореЗрдВ 
тАУfilter рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛, рдЬреЛ рдЖрдкрдХреЛ рдЙрди рдлрд╛рдЗрд▓реЛрдВ рдХреЗ рд╕реЗрдЯ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдЬрд┐рди рдкрд░ рд╣рдо рдореНрдпреВрдЯреЗрд╢рди рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред
 ./vendor/bin/infection --filter=Calculator.php 
рдЭреВрдареА рд╕рдХрд╛рд░рд╛рддреНрдордХрддрд╛
рдХреБрдЫ рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди рдХреЛрдб рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рд╕рдВрдХреНрд░рдордг 100% рд╕реЗ рдХрдо рдПрдордПрд╕рдЖрдИ рджреЗрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рд╣рдо рд╣рдореЗрд╢рд╛ рдЗрд╕рдХреЗ рд╕рд╛рде рдХреБрдЫ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдРрд╕реА рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдЖрдирд╛ рд╣реЛрдЧрд╛ред рдРрд╕рд╛ рд╣реА рдХреБрдЫ рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ:
 public function calcNumber(int $a): int { return $a / $this->getRatio(); } private function getRatio(): int { return 1; } 
рдмреЗрд╢рдХ, рдпрд╣рд╛рдБ 
getRatio рдкрджреНрдзрддрд┐ рдХрд╛ 
getRatio рдирд╣реАрдВ рд╣реИ, рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ, рд╕рдВрднрд╡рддрдГ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреА рдЧрдгрдирд╛ рд╣реЛрдЧреАред рд▓реЗрдХрд┐рди рдкрд░рд┐рдгрд╛рдо 
1 рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд╕рдВрдХреНрд░рдордг рд░рд┐рдЯрд░реНрди:
 Escaped mutants: ================ 1) /home/sarven/projects/infection-playground/infection-playground/src/Calculator.php:26 [M] Division --- Original +++ New @@ @@ public function calcNumber(int $a) : int { - return $a / $this->getRatio(); + return $a * $this->getRatio(); } private function getRatio() : int 
рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ, рдореВрд▓ рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдмрд░рд╛рдмрд░, 1 рд╕реЗ рдЧреБрдгрд╛ рдХрд░рдирд╛ рдФрд░ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдирд╛ рдПрдХ рд╣реА рдкрд░рд┐рдгрд╛рдо рджреЗрддрд╛ рд╣реИред рддреЛ рдпрд╣ рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдирд╣реАрдВ рддреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рд╣рдорд╛рд░реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреА рд╕рдЯреАрдХрддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕рдВрдХреНрд░рдордг рдХреЗ рд╡рд┐рдЪреНрдЫреЗрджрди рдХреЗ рдмрд╛рд╡рдЬреВрдж, рд╕рдм рдХреБрдЫ рдХреНрд░рдо рдореЗрдВ рд╣реИред
рдмрдбрд╝реА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдХреВрд▓рди
рдмрдбрд╝реА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕рдВрдХреНрд░рдордг рдмрд╣реБрдд рд╕рдордп рд▓реЗ рд╕рдХрддрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рдХреЗрд╡рд▓ рд╕рдВрд╢реЛрдзрд┐рдд рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдЖрдк CI рдХреЗ рджреМрд░рд╛рди рдирд┐рд╖реНрдкрд╛рджрди рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП, рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рджреЗрдЦреЗрдВ: 
https://infection.imtqy.com/guide/how-to.htmlрдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдк рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ рд╕рдВрд╢реЛрдзрд┐рдд рдХреЛрдб рдкрд░ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рдХреЗрд╡рд▓ рддрднреА рд╕рдВрднрд╡ рд╣реИ рдЬрдм рд╕рднреА рдкрд░реАрдХреНрд╖рдг рд╕реНрд╡рддрдВрддреНрд░ рд╣реЛрдВред рдЕрд░реНрдерд╛рддреН, рдРрд╕реЗ рдкрд░реАрдХреНрд╖рдг рдЕрдЪреНрдЫреЗ рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдПред рдЗрд╕ рд╡рд┐рдХрд▓реНрдк рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП 
тАУthreads рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:
 ./vendor/bin/infection --threads=4 
рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ?
Infection рдврд╛рдВрдЪреЗ рдореЗрдВ AST (Abstract Syntax Tree) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдПрдХ рд╕рд╛рд░ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдХреЛрдб рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рд▓рд┐рдП, PHP ( 
php-parser ) рдХреЗ рд░рдЪрдирд╛рдХрд╛рд░реЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдЦреЗ рдЧрдП 
рдкрд╛рд░реНрд╕рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдЙрдкрдХрд░рдг рдХреЗ рд╕рд░рд▓реАрдХреГрдд рд╕рдВрдЪрд╛рд▓рди рдХреЛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
- рдХреЛрдб рдЖрдзрд╛рд░рд┐рдд рдПрдПрд╕рдЯреА рдкреАрдврд╝реАред
 
- рдЙрдкрдпреБрдХреНрдд рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди (рдкреВрд░реНрдг рд╕реВрдЪреА рдпрд╣рд╛рдВ рд╣реИ ) рдХрд╛ рдЙрдкрдпреЛрдЧред
 
- рдПрдПрд╕рдЯреА рдЖрдзрд╛рд░рд┐рдд рд╕рдВрд╢реЛрдзрд┐рдд рдХреЛрдб рдмрдирд╛рдПрдБред
 
- рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХреЛрдб рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдПрдВред
 
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдорд╛рдЗрдирд╕ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдореНрдпреВрдЯреЗрдЯрд░ рдкреНрд▓рд╕ рдХреА рдЬрд╛рдВрдЪ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
 <?php declare(strict_types=1); namespace Infection\Mutator\Arithmetic; use Infection\Mutator\Util\Mutator; use PhpParser\Node; use PhpParser\Node\Expr\Array_;  final class Plus extends Mutator {  public function mutate(Node $node) { return new Node\Expr\BinaryOp\Minus($node->left, $node->right, $node->getAttributes()); } protected function mutatesNode(Node $node): bool { if (!($node instanceof Node\Expr\BinaryOp\Plus)) { return false; } if ($node->left instanceof Array_ || $node->right instanceof Array_) { return false; } return true; } } 
mutate() рд╡рд┐рдзрд┐ рдПрдХ рдирдпрд╛ рддрддреНрд╡ рдмрдирд╛рддреА рд╣реИ, рдЬрд┐рд╕реЗ рдПрдХ рдкреНрд▓рд╕ рджреНрд╡рд╛рд░рд╛ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред 
Node рд╡рд░реНрдЧ php-parser рдкреИрдХреЗрдЬ рд╕реЗ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ; рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдПрд╕рдЯреА рдкрд░рд┐рдЪрд╛рд▓рдиреЛрдВ рдХреЗ рд▓рд┐рдП рдФрд░ PHP рдХреЛрдб рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрд╣ рдкрд░рд┐рд╡рд░реНрддрди рдХрд╣реАрдВ рднреА рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП 
mutatesNode() рд╡рд┐рдзрд┐ рдореЗрдВ рдЕрддрд┐рд░рд┐рдХреНрдд рд╢рд░реНрддреЗрдВ рд╣реИрдВред рдпрджрд┐ рдкреНрд▓рд╕ рдХреЗ рдмрд╛рдИрдВ рдУрд░ рдпрд╛ рдорд╛рдЗрдирд╕ рдХреЗ рджрд╛рдИрдВ рдУрд░ рдПрдХ рд╕рд░рдгреА рд╣реИ, рддреЛ рдкрд░рд┐рд╡рд░реНрддрди рдЕрд╕реНрд╡реАрдХрд╛рд░реНрдп рд╣реИред рдЗрд╕ рдХреЛрдб рдХреЗ рдХрд╛рд░рдг рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
 $tab = [0] + [1]; is correct, but the following one isn't correct. $tab = [0] - [1]; 
рдкрд░рд┐рдгрд╛рдо
рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди рдкрд░реАрдХреНрд╖рдг рдПрдХ рдЙрддреНрдХреГрд╖реНрдЯ рдЙрдкрдХрд░рдг рд╣реИ рдЬреЛ рд╕реАрдЖрдИ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдкреВрд░рдХ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЖрдкрдХреЛ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреА рдЧреБрдгрд╡рддреНрддрд╛ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреА рд╣рд░реА рд╣рд╛рдЗрд▓рд╛рдЗрдЯрд┐рдВрдЧ рд╣рдореЗрдВ рд╡рд┐рд╢реНрд╡рд╛рд╕ рдирд╣реАрдВ рджрд┐рд▓рд╛рддреА рд╣реИ рдХрд┐ рд╕рдм рдХреБрдЫ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИред рдЖрдк рдореНрдпреВрдЯреЗрд╢рдирд▓ рдкрд░реАрдХреНрд╖рдг - рдпрд╛ рдкрд░реАрдХреНрд╖рдг рдкрд░реАрдХреНрд╖рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреА рд╕рдЯреАрдХрддрд╛ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рдЬреЛ рд╕рдорд╛рдзрд╛рди рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рд╣рдорд╛рд░реЗ рдЖрддреНрдорд╡рд┐рд╢реНрд╡рд╛рд╕ рдХреЛ рдмрдврд╝рд╛рддрд╛ рд╣реИред рдмреЗрд╢рдХ, рдореИрдЯреНрд░рд┐рдХреНрд╕ рдХреЗ 100% рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░рдпрд╛рд╕ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╣рдореЗрд╢рд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рдЖрдкрдХреЛ рд▓реЙрдЧ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдиреЗ рдФрд░ рддрджрдиреБрд╕рд╛рд░ рдкрд░реАрдХреНрд╖рдг рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред