Skip to content

Commit

Permalink
Improve ConcatSwitchSides mutator and fix diff printing
Browse files Browse the repository at this point in the history
  • Loading branch information
gehrisandro committed Nov 24, 2023
1 parent 0fab9b4 commit ba63261
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 2 deletions.
2 changes: 1 addition & 1 deletion WIP.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

# Backlog Prio 1
- [ ] Fix PHPStorm indexing Issues. Maybe do not end cached files with .php?
- [ ] Automatically empty cache when package version changes
- [ ] Automatically empty cache when package version changes / Maybe there is another approach: Use the same cache key per php file, but store a hash of the file content and the package version in the cache. If the hash changes, the cache is invalid.
- [ ] What should we do with interfaces? ignore them completely?
- [ ] Finish: Disable mutations by annotation
- [ ] Run mutations in a reasonable order: New, Survived, NotCovered, Skipped, Killed (Survived first, if --stop-on-survived or --bail; NotCovered first, if --stop-on-uncovered)
Expand Down
7 changes: 6 additions & 1 deletion src/Mutation.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use PhpParser\PrettyPrinter\Standard;
use SebastianBergmann\Diff\Differ;
use SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Finder\SplFileInfo;

class Mutation
Expand Down Expand Up @@ -89,11 +90,15 @@ private static function diff(string $originalSource, string $modifiedSource): st
$diff = (new Differ(new UnifiedDiffOutputBuilder("\n--- Expected\n+++ Actual\n")))
->diff($originalSource, $modifiedSource);

if (! str_contains($diff, self::DIFF_SEPARATOR)) {
return '';
}

$tmp = '';
$lines = explode(PHP_EOL, explode(self::DIFF_SEPARATOR, $diff)[1]);

foreach ($lines as $line) {
$tmp .= self::colorizeLine($line, str_starts_with($line, '-') ? 'red' : (str_starts_with($line, '+') ? 'green' : 'gray')).PHP_EOL;
$tmp .= self::colorizeLine(OutputFormatter::escape($line), str_starts_with($line, '-') ? 'red' : (str_starts_with($line, '+') ? 'green' : 'gray')).PHP_EOL;
}

$diff = str_replace(explode(self::DIFF_SEPARATOR, $diff)[1], $tmp, $diff);
Expand Down
30 changes: 30 additions & 0 deletions src/Mutators/String/ConcatSwitchSides.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
use Pest\Mutate\Mutators\Abstract\AbstractMutator;
use PhpParser\Node;
use PhpParser\Node\Expr\BinaryOp\Concat;
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Scalar\String_;

class ConcatSwitchSides extends AbstractMutator
{
Expand All @@ -24,6 +27,33 @@ public static function nodesToHandle(): array
return [Concat::class];
}

public static function can(Node $node): bool
{
if (! $node instanceof Concat) {
return false;
}

if ($node->left->getType() !== $node->right->getType()) {
return true;
}

if ($node->left instanceof ConstFetch && $node->right instanceof ConstFetch) {
return $node->left->name->toString() !== $node->right->name->toString();
}

if ($node->left instanceof String_ && $node->right instanceof String_) {
return $node->left->value !== $node->right->value;
}
if (! $node->left instanceof Variable) {
return true;
}
if (! $node->right instanceof Variable) {
return true;
}

return $node->left->name !== $node->right->name;
}

public static function mutate(Node $node): Node
{
/** @var Concat $node */
Expand Down
24 changes: 24 additions & 0 deletions tests/Mutators/String/ConcatSwitchSidesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,27 @@
return $a + $b;
CODE);
})->expectExceptionMessage('No mutation performed');

it('does not mutate if both sides are equal strings', function (): void {
mutateCode(ConcatSwitchSides::class, <<<'CODE'
<?php
return 'a' . 'a';
CODE);
})->expectExceptionMessage('No mutation performed');

it('does not mutate if both sides are equal const fetches', function (): void {
mutateCode(ConcatSwitchSides::class, <<<'CODE'
<?php
return PHP_EOL . PHP_EOL;
CODE);
})->expectExceptionMessage('No mutation performed');

it('does not mutate if both sides are equal variables', function (): void {
mutateCode(ConcatSwitchSides::class, <<<'CODE'
<?php
return $a . $a;
CODE);
})->expectExceptionMessage('No mutation performed');

0 comments on commit ba63261

Please sign in to comment.