From 4f745da14c27f142325d38a9759d9f34fa644ae9 Mon Sep 17 00:00:00 2001 From: Simon Bigelmayr Date: Thu, 14 Nov 2024 16:56:41 +0100 Subject: [PATCH] feat: Add PHPStan-Rule `MLL\Utils\PHPStan\Rules\VariableNameIdToIDRule` (#40) --- CHANGELOG.md | 6 ++ src/PHPStan/Rules/VariableNameIdToIDRule.php | 56 ++++++++++++++++++ .../Rules/VariableNameIdToIDRuleTest.php | 58 +++++++++++++++++++ tests/Tecan/TecanProtocolTest.php | 2 +- 4 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 src/PHPStan/Rules/VariableNameIdToIDRule.php create mode 100644 tests/PHPStan/Rules/VariableNameIdToIDRuleTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index d9ed358..79dbdaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/src/PHPStan/Rules/VariableNameIdToIDRule.php b/src/PHPStan/Rules/VariableNameIdToIDRule.php new file mode 100644 index 0000000..7968f00 --- /dev/null +++ b/src/PHPStan/Rules/VariableNameIdToIDRule.php @@ -0,0 +1,56 @@ + */ +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(<<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); + } +} diff --git a/tests/PHPStan/Rules/VariableNameIdToIDRuleTest.php b/tests/PHPStan/Rules/VariableNameIdToIDRuleTest.php new file mode 100644 index 0000000..d6499ba --- /dev/null +++ b/tests/PHPStan/Rules/VariableNameIdToIDRuleTest.php @@ -0,0 +1,58 @@ + */ + 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 */ + 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 */ + public static function wrongToRight(): iterable + { + yield ['Id', 'id']; + yield ['labId', 'labID']; + yield ['labIds', 'labIDs']; + } +} diff --git a/tests/Tecan/TecanProtocolTest.php b/tests/Tecan/TecanProtocolTest.php index 87cefcf..53943b9 100644 --- a/tests/Tecan/TecanProtocolTest.php +++ b/tests/Tecan/TecanProtocolTest.php @@ -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