Skip to content

Smarter IdenticalEqual mutator #2111

@staabm

Description

@staabm

I am currently playing with the tool and look into how it behaves.

Using the perMutator logger I had a look which mutators are applied most when running infection on its own codebase.

One interessting Mutator which came to my eyes is IdenticalEqual for which I had a look into the mutations with ./build/infection.phar --mutators=IdenticalEqual --debug -s. Here a few interessting examples:

179) /Users/staabm/workspace/infection/src/Str.php:82    [M] IdenticalEqual

@@ @@
         // Trim trailing empty lines
         for ($i = $linesCount - 1; $i >= 0; --$i) {
             $line = $lines[$i];
-            if (trim($line) === '') {
+            if (trim($line) == '') {
                 unset($lines[$i]);
                 continue;
             }
...
182) /Users/staabm/workspace/infection/src/TestFramework/CommandLineBuilder.php:128    [M] IdenticalEqual

@@ @@
     }
     private function isBatchFile(string $path): bool
     {
-        return substr($path, -self::BAT_EXTENSION_LENGTH) === '.bat';
+        return substr($path, -self::BAT_EXTENSION_LENGTH) == '.bat';
     }
 }
...
183) /Users/staabm/workspace/infection/src/TestFramework/Coverage/CoverageChecker.php:132    [M] IdenticalEqual

@@ @@
                 $errors[] = sprintf('- The JUnit file could not be found: %s', $exception->getMessage());
             }
         }
-        if (count($errors) === 0) {
+        if (count($errors) == 0) {
             return;
         }
         $message = sprintf(<<<TXT

...
202) /Users/staabm/workspace/infection/src/TestFramework/Coverage/XmlReport/XmlCoverageParser.php:156    [M] IdenticalEqual

@@ @@
     {
         $methodsCoverage = [];
         foreach ($methodsCoverageNodes as $methodsCoverageNode) {
-            if ((int) $methodsCoverageNode->getAttribute('coverage') === 0) {
+            if ((int) $methodsCoverageNode->getAttribute('coverage') == 0) {
                 continue;
             }
             $methodName = $methodsCoverageNode->getAttribute('name');
...

213) /Users/staabm/workspace/infection/src/TestFramework/PhpUnit/Adapter/PhpUnitAdapter.php:138    [M] IdenticalEqual

@@ @@
     }
     public function isSyntaxError(string $output): bool
     {
-        return preg_match('/ParseError: syntax error/i', $output) === 1;
+        return preg_match('/ParseError: syntax error/i', $output) == 1;
     }
     public function getMemoryUsed(string $output): float
     {

...
225) /Users/staabm/workspace/infection/src/TestFramework/PhpUnit/Config/XmlConfigurationVersionProvider.php:96    [M] IdenticalEqual

@@ @@
          * https://schema.phpunit.de/9.3/phpunit.xsd
          */
         $match = [];
-        if (preg_match('#(\d+\.\d)(/phpunit)?\.xsd$#', $schemaUri, $match) === 1) {
+        if (preg_match('#(\d+\.\d)(/phpunit)?\.xsd$#', $schemaUri, $match) == 1) {
             return $match[1];
         }
         // Without any clues we assume it's a legacy version: it's most prevalent

what these examples have in common: I think for the cases it does not make a difference whether we compare using equal or identcal, because we work on php builtin functions (for which we could lookup the return type - or hardcode a list for the most common ones) and the comparisons evaluated work on same types.

<int> === <int> is the same as <int> == <int> (for all scalar types).

this knowledge could be utilized to reduce number of mutations and therefore speedup infection runs.

wdyt?

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions