Skip to content

Commit

Permalink
feat: Add PHPStan-Rule `MLL\Utils\PHPStan\Rules\VariableNameIdToIDRul…
Browse files Browse the repository at this point in the history
…e` (#40)
  • Loading branch information
simbig authored Nov 14, 2024
1 parent 3371142 commit 4f745da
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 1 deletion.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ See [GitHub releases](https://github.com/mll-lab/php-utils/releases).

## Unreleased

## v5.7.0

### Added

- Add PHPStan-Rule `MLL\Utils\PHPStan\Rules\VariableNameIdToIDRule`

## v5.6.0

### Added
Expand Down
56 changes: 56 additions & 0 deletions src/PHPStan/Rules/VariableNameIdToIDRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php declare(strict_types=1);

namespace MLL\Utils\PHPStan\Rules;

use Illuminate\Support\Str;
use PhpParser\Node;
use PhpParser\Node\Expr\Variable;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;

/** @implements Rule<Variable> */
class VariableNameIdToIDRule implements Rule
{
/** Lists words or phrases that contain "Id" but are fine. */
protected const FALSE_POSITIVES = ['Identifier'];

public function getNodeType(): string
{
return Variable::class;
}

public function processNode(Node $node, Scope $scope): array
{
$nodeName = $node->name;

if (is_string($nodeName)
&& static::containsWrongIDCapitalization($nodeName)
) {
$expectedName = static::fixIDCapitalization($nodeName);

return [
RuleErrorBuilder::message(<<<TXT
Variable name "\${$nodeName}" should use "ID" instead of "Id", rename it to "\${$expectedName}".
TXT)->build(),
];
}

return [];
}

public static function containsWrongIDCapitalization(string $nodeName): bool
{
return \Safe\preg_match('/Id/', $nodeName) === 1
&& ! Str::contains($nodeName, self::FALSE_POSITIVES);
}

public static function fixIDCapitalization(string $nodeName): string
{
if ($nodeName === 'Id') {
return 'id';
}

return str_replace('Id', 'ID', $nodeName);
}
}
58 changes: 58 additions & 0 deletions tests/PHPStan/Rules/VariableNameIdToIDRuleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php declare(strict_types=1);

namespace MLL\Utils\Tests\PHPStan\Rules;

use MLL\Utils\PHPStan\Rules\VariableNameIdToIDRule;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;

final class VariableNameIdToIDRuleTest extends TestCase
{
/** @dataProvider wrongID */
#[DataProvider('wrongID')]
public function testRecognizesWrongCapitalizations(string $variableName): void
{
self::assertTrue(VariableNameIdToIDRule::containsWrongIDCapitalization($variableName));
}

/** @return iterable<array{string}> */
public static function wrongID(): iterable
{
yield ['Id'];
yield ['labId'];
yield ['labIds'];
}

/** @dataProvider correctID */
#[DataProvider('correctID')]
public function testAllowsCorrectCapitalizations(string $variableName): void
{
self::assertFalse(VariableNameIdToIDRule::containsWrongIDCapitalization($variableName));
}

/** @return iterable<array{string}> */
public static function correctID(): iterable
{
yield ['id'];
yield ['ids'];
yield ['test_id'];
yield ['labID'];
yield ['labIDs'];
yield ['testIdentifier'];
}

/** @dataProvider wrongToRight */
#[DataProvider('wrongToRight')]
public function testFixIDCapitalization(string $wrong, string $right): void
{
self::assertSame($right, VariableNameIdToIDRule::fixIDCapitalization($wrong));
}

/** @return iterable<array{string, string}> */
public static function wrongToRight(): iterable
{
yield ['Id', 'id'];
yield ['labId', 'labID'];
yield ['labIds', 'labIDs'];
}
}
2 changes: 1 addition & 1 deletion tests/Tecan/TecanProtocolTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public function testProtocolUuidName(): void
self::assertTrue(Str::isUuid($fileName));

$fileSuffix = Str::after($tecanProtocol->fileName(), $fileName);
self::assertSame($fileSuffix, TecanProtocol::GEMINI_WORKLIST_FILENAME_SUFFIX);
self::assertSame(TecanProtocol::GEMINI_WORKLIST_FILENAME_SUFFIX, $fileSuffix);
}

public function testProtocolWithForFourTips(): void
Expand Down

0 comments on commit 4f745da

Please sign in to comment.