From ef9de6b060917c01f0a03b6d754f29489d40e248 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 24 Nov 2025 23:07:18 +1100 Subject: [PATCH 1/2] Revert "Removed camelCase format tests that were incompatible with PHPCS 3." This reverts commit 135ce694d67419311e15e318ca3f1c8367979095. --- tests/Unit/LocalVariableNamingSniffTest.php | 79 +++++++++++++++++++++ tests/Unit/ParameterNamingSniffTest.php | 79 +++++++++++++++++++++ 2 files changed, 158 insertions(+) diff --git a/tests/Unit/LocalVariableNamingSniffTest.php b/tests/Unit/LocalVariableNamingSniffTest.php index 5736aa0..3f7f48f 100644 --- a/tests/Unit/LocalVariableNamingSniffTest.php +++ b/tests/Unit/LocalVariableNamingSniffTest.php @@ -4,6 +4,7 @@ namespace DrevOps\PhpcsStandard\Tests\Unit; +use PHP_CodeSniffer\Config; use PHP_CodeSniffer\Ruleset; use DrevOps\Sniffs\NamingConventions\LocalVariableNamingSniff; use PHPUnit\Framework\Attributes\CoversClass; @@ -121,4 +122,82 @@ public static function dataProviderProcess(): array { ]; } + /** + * Test process method with camelCase format. + * + * @param string $code + * PHP code to test. + * @param bool $should_have_errors + * Whether errors should be detected. + */ + #[DataProvider('dataProviderProcessWithCamelCaseFormat')] + public function testProcessWithCamelCaseFormat(string $code, bool $should_have_errors): void { + // Create a new config with camelCase format property. + $config = new Config(); + $config->standards = ['DrevOps']; + $config->sniffs = ['DrevOps.NamingConventions.LocalVariableNaming']; + + // Create temporary ruleset XML with property configuration. + $ruleset_xml = ' + + + + + + +'; + + $ruleset_file = tempnam(sys_get_temp_dir(), 'phpcs_ruleset_'); + file_put_contents($ruleset_file, $ruleset_xml); + + try { + $config->standards = [$ruleset_file]; + $this->ruleset = new Ruleset($config); + + $file = $this->processCode($code); + $errors = $file->getErrors(); + + if ($should_have_errors) { + $this->assertNotEmpty($errors); + } + else { + $this->assertEmpty($errors); + } + } + finally { + unlink($ruleset_file); + } + } + + /** + * Data provider for camelCase format tests. + * + * @return array> + * Test cases. + */ + public static function dataProviderProcessWithCamelCaseFormat(): array { + return [ + 'valid_camel_case_variable' => [ + ' [ + ' [ + ' [ + ' [ + 'standards = ['DrevOps']; + $config->sniffs = ['DrevOps.NamingConventions.ParameterNaming']; + + // Create temporary ruleset XML with property configuration. + $ruleset_xml = ' + + + + + + +'; + + $ruleset_file = tempnam(sys_get_temp_dir(), 'phpcs_ruleset_'); + file_put_contents($ruleset_file, $ruleset_xml); + + try { + $config->standards = [$ruleset_file]; + $this->ruleset = new Ruleset($config); + + $file = $this->processCode($code); + $errors = $file->getErrors(); + + if ($should_have_errors) { + $this->assertNotEmpty($errors); + } + else { + $this->assertEmpty($errors); + } + } + finally { + unlink($ruleset_file); + } + } + + /** + * Data provider for camelCase format tests. + * + * @return array> + * Test cases. + */ + public static function dataProviderProcessWithCamelCaseFormat(): array { + return [ + 'valid_camel_case_parameter' => [ + ' [ + ' [ + ' [ + ' [ + ' Date: Mon, 24 Nov 2025 23:07:18 +1100 Subject: [PATCH 2/2] Revert "Refactored case sniffs to allow choosing snake or camel case." This reverts commit 6e7350e22a3d4e5fef3f979dd1de6061d07db468. --- CLAUDE.md | 80 +++---- README.md | 70 ++---- composer.json | 13 +- ...ngSniff.php => AbstractSnakeCaseSniff.php} | 83 +------ ...ff.php => LocalVariableSnakeCaseSniff.php} | 33 +-- ...gSniff.php => ParameterSnakeCaseSniff.php} | 35 +-- src/DrevOps/ruleset.xml | 14 +- ...lVariableSnakeCaseSniffFunctionalTest.php} | 46 ++-- ...ParameterSnakeCaseSniffFunctionalTest.php} | 30 +-- ...=> AbstractVariableSnakeCaseSniffTest.php} | 210 ++---------------- ...hp => LocalVariableSnakeCaseSniffTest.php} | 98 +------- ...st.php => ParameterSnakeCaseSniffTest.php} | 102 +-------- 12 files changed, 154 insertions(+), 660 deletions(-) rename src/DrevOps/Sniffs/NamingConventions/{AbstractVariableNamingSniff.php => AbstractSnakeCaseSniff.php} (87%) rename src/DrevOps/Sniffs/NamingConventions/{LocalVariableNamingSniff.php => LocalVariableSnakeCaseSniff.php} (59%) rename src/DrevOps/Sniffs/NamingConventions/{ParameterNamingSniff.php => ParameterSnakeCaseSniff.php} (82%) rename tests/Functional/{LocalVariableNamingSniffFunctionalTest.php => LocalVariableSnakeCaseSniffFunctionalTest.php} (57%) rename tests/Functional/{ParameterNamingSniffFunctionalTest.php => ParameterSnakeCaseSniffFunctionalTest.php} (83%) rename tests/Unit/{AbstractVariableNamingSniffTest.php => AbstractVariableSnakeCaseSniffTest.php} (67%) rename tests/Unit/{LocalVariableNamingSniffTest.php => LocalVariableSnakeCaseSniffTest.php} (52%) rename tests/Unit/{ParameterNamingSniffTest.php => ParameterSnakeCaseSniffTest.php} (62%) diff --git a/CLAUDE.md b/CLAUDE.md index f093ec0..3c4e821 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,12 +4,11 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Project Overview -This is a PHP_CodeSniffer (PHPCS) standard package (`drevops/phpcs-standard`) that enforces custom coding conventions, specifically focused on configurable naming (snakeCase or camelCase) for local variables and parameters. +This is a PHP_CodeSniffer (PHPCS) standard package (`drevops/phpcs-standard`) that enforces custom coding conventions, specifically focused on snake_case naming for local variables and parameters. **Key Goals:** -- Enforce consistent naming conventions for local variables and function/method parameters -- Support configurable formats: snakeCase (default) or camelCase -- Exclude class properties from naming enforcement (properties follow different conventions) +- Enforce snake_case for local variables and function/method parameters +- Exclude class properties from snake_case enforcement (properties follow different conventions) - Preserve inherited parameter names from interfaces and parent classes - Provide auto-fixing support via `phpcbf` - Provide a standalone, reusable PHPCS standard for the DrevOps ecosystem @@ -50,8 +49,8 @@ Coverage reports are generated in: Run a single test file: ```bash ./vendor/bin/phpunit tests/Unit/AbstractVariableSnakeCaseSniffTest.php -./vendor/bin/phpunit tests/Unit/LocalVariableNamingSniffTest.php -./vendor/bin/phpunit tests/Unit/ParameterNamingSniffTest.php +./vendor/bin/phpunit tests/Unit/LocalVariableSnakeCaseSniffTest.php +./vendor/bin/phpunit tests/Unit/ParameterSnakeCaseSniffTest.php ``` Run only unit tests or functional tests: @@ -87,15 +86,15 @@ composer normalize --dry-run ### Directory Structure - `src/DrevOps/` - Source code for the PHPCS standard - `Sniffs/NamingConventions/` - - `AbstractVariableNamingSniff.php` - Base class with shared functionality - - `LocalVariableNamingSniff.php` - Enforces snake_case for local variables - - `ParameterNamingSniff.php` - Enforces snake_case for parameters + - `AbstractSnakeCaseSniff.php` - Base class with shared functionality + - `LocalVariableSnakeCaseSniff.php` - Enforces snake_case for local variables + - `ParameterSnakeCaseSniff.php` - Enforces snake_case for parameters - `ruleset.xml` - DrevOps standard definition - `tests/` - PHPUnit tests organized by type: - `Unit/` - Unit tests for individual sniff methods (using reflection) - `AbstractVariableSnakeCaseSniffTest.php` - Tests shared base class methods - - `LocalVariableNamingSniffTest.php` - Tests local variable sniff - - `ParameterNamingSniffTest.php` - Tests parameter sniff + - `LocalVariableSnakeCaseSniffTest.php` - Tests local variable sniff + - `ParameterSnakeCaseSniffTest.php` - Tests parameter sniff - `UnitTestCase.php` - Base test class with helper methods - `Functional/` - Integration tests that run actual phpcs commands - `Fixtures/` - Test fixture files with intentional violations @@ -106,22 +105,15 @@ composer normalize --dry-run The standard uses an **abstract base class pattern** with two concrete implementations: -#### AbstractVariableNamingSniff +#### AbstractSnakeCaseSniff -Base class (src/DrevOps/Sniffs/NamingConventions/AbstractVariableNamingSniff.php) containing shared functionality: - -**Public property:** -- `$format` - Configurable naming convention ('snakeCase' or 'camelCase', default: 'snakeCase') +Base class (src/DrevOps/Sniffs/NamingConventions/AbstractSnakeCaseSniff.php) containing shared functionality: **Core methods:** - `register()` - Registers T_VARIABLE token for processing - `isReserved()` - Identifies PHP reserved variables ($this, $_GET, etc.) - `isSnakeCase()` - Validates snake_case format using regex -- `isCamelCase()` - Validates camelCase format using regex -- `isValidFormat()` - Validates variable name against configured format -- `toSnakeCase()` - Converts variable name to snake_case -- `toCamelCase()` - Converts variable name to camelCase -- `toFormat()` - Converts variable name to the configured format +- `toSnakeCase()` - Converts camelCase to snake_case for suggestions **Helper methods:** - `getParameterNames()` - Extracts parameter names from function signature @@ -132,33 +124,29 @@ Base class (src/DrevOps/Sniffs/NamingConventions/AbstractVariableNamingSniff.php - `isProperty()` - Distinguishes class properties from local variables - `isInheritedParameter()` - Detects parameters from interfaces/parent classes -#### LocalVariableNamingSniff +#### LocalVariableSnakeCaseSniff -Enforces configurable naming convention for **local variables** inside functions/methods. +Enforces snake_case for **local variables** inside functions/methods. **What gets checked:** - ✅ Local variables inside function/method bodies -- ❌ Function/method parameters (handled by ParameterNaming) +- ❌ Function/method parameters (handled by ParameterSnakeCase) - ❌ Class properties (not enforced) - ❌ Reserved PHP variables ($this, superglobals, etc.) -**Error codes:** -- `DrevOps.NamingConventions.LocalVariableNaming.NotSnakeCase` (when format='snakeCase') -- `DrevOps.NamingConventions.LocalVariableNaming.NotCamelCase` (when format='camelCase') +**Error code:** `DrevOps.NamingConventions.LocalVariableSnakeCase.NotSnakeCase` -#### ParameterNamingSniff +#### ParameterSnakeCaseSniff -Enforces configurable naming convention for **function/method parameters**. +Enforces snake_case for **function/method parameters**. **What gets checked:** - ✅ Function and method parameters (in signature only) -- ❌ Local variables (handled by LocalVariableNaming) +- ❌ Local variables (handled by LocalVariableSnakeCase) - ❌ Parameters inherited from interfaces/parent classes/abstract methods - ❌ Promoted constructor properties -**Error codes:** -- `DrevOps.NamingConventions.ParameterNaming.NotSnakeCase` (when format='snakeCase') -- `DrevOps.NamingConventions.ParameterNaming.NotCamelCase` (when format='camelCase') +**Error code:** `DrevOps.NamingConventions.ParameterSnakeCase.NotSnakeCase` ### PHPCS Standard Registration @@ -181,16 +169,16 @@ Tests are organized by class hierarchy: **AbstractVariableSnakeCaseSniffTest.php** - Tests all shared base class methods using reflection - Tests: `isSnakeCase()`, `toSnakeCase()`, `isReserved()`, `register()`, `getParameterNames()`, `isProperty()`, `isPromotedProperty()`, `isInheritedParameter()` -- Each test uses concrete sniff instances (LocalVariableNamingSniff or ParameterNamingSniff) to access protected methods +- Each test uses concrete sniff instances (LocalVariableSnakeCaseSniff or ParameterSnakeCaseSniff) to access protected methods -**LocalVariableNamingSniffTest.php** +**LocalVariableSnakeCaseSniffTest.php** - Tests sniff-specific logic: error code constant and `process()` method -- Configured to run only LocalVariableNaming sniff in isolation +- Configured to run only LocalVariableSnakeCase sniff in isolation - Validates that local variables are checked and parameters are skipped -**ParameterNamingSniffTest.php** +**ParameterSnakeCaseSniffTest.php** - Tests sniff-specific logic: error code constant, `register()`, and `process()` method -- Configured to run only ParameterNaming sniff in isolation +- Configured to run only ParameterSnakeCase sniff in isolation - Validates that parameters are checked and local variables are skipped - Includes tests for inherited parameter detection @@ -202,15 +190,15 @@ Tests are organized by class hierarchy: #### 2. Functional Tests -**LocalVariableNamingSniffFunctionalTest.php** +**LocalVariableSnakeCaseSniffFunctionalTest.php** - Run actual `phpcs` commands as external processes - Test complete PHPCS integration with JSON output parsing -- Verify LocalVariableNaming sniff detection and error codes +- Verify LocalVariableSnakeCase sniff detection and error codes -**ParameterNamingSniffFunctionalTest.php** +**ParameterSnakeCaseSniffFunctionalTest.php** - Run actual `phpcs` commands as external processes - Test complete PHPCS integration with JSON output parsing -- Verify ParameterNaming sniff detection and error codes +- Verify ParameterSnakeCase sniff detection and error codes Tests include: - Confirms violations are detected with correct error codes @@ -251,7 +239,7 @@ When implementing or modifying sniffs: 1. Place sniff classes in `src/DrevOps/Sniffs/` following PHPCS naming conventions - Format: `CategoryName/SniffNameSniff.php` - - Example: `NamingConventions/LocalVariableNamingSniff.php` + - Example: `NamingConventions/LocalVariableSnakeCaseSniff.php` 2. Consider using abstract base classes for shared functionality across related sniffs 3. Implement the `Sniff` interface from `PHP_CodeSniffer\Sniffs\Sniff` 4. Use `declare(strict_types=1);` at the top of all PHP files @@ -266,10 +254,8 @@ When implementing or modifying sniffs: 10. Create fixture files in `tests/Fixtures/` with intentional violations 11. Follow error code naming: `StandardName.Category.SniffName.ErrorName` - Examples: - - `DrevOps.NamingConventions.LocalVariableNaming.NotSnakeCase` - - `DrevOps.NamingConventions.LocalVariableNaming.NotCamelCase` - - `DrevOps.NamingConventions.ParameterNaming.NotSnakeCase` - - `DrevOps.NamingConventions.ParameterNaming.NotCamelCase` + - `DrevOps.NamingConventions.LocalVariableSnakeCase.NotSnakeCase` + - `DrevOps.NamingConventions.ParameterSnakeCase.NotSnakeCase` ## CI/CD diff --git a/README.md b/README.md index e0b7fb6..8b7e69d 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ --- PHP_CodeSniffer standard enforcing: -- Consistent naming conventions for local variables and function/method parameters (configurable: `snakeCase` or `camelCase`) +- `snake_case` naming for local variables and function/method parameters - PHPUnit data provider naming conventions and organization ## Installation @@ -60,8 +60,8 @@ Use individual sniffs: ```xml - - + + @@ -70,77 +70,40 @@ Use individual sniffs: ``` -### Configure naming convention +## `LocalVariableSnakeCase` -By default, both sniffs enforce `snakeCase`. Configure to use `camelCase`: +Enforces `snake_case` for local variables inside functions/methods. -```xml - - - - - - - - - - - - - -``` - -## `LocalVariableNaming` - -Enforces consistent naming convention for local variables inside functions/methods. - -**With `snakeCase` (default):** ```php function processOrder() { $order_id = 1; // ✓ Valid - $orderId = 1; // ✗ Error: NotSnakeCase -} -``` - -**With `camelCase`:** -```php -function processOrder() { - $orderId = 1; // ✓ Valid - $order_id = 1; // ✗ Error: NotCamelCase + $orderId = 1; // ✗ Error: VariableNotSnakeCase } ``` Excludes: -- Function/method parameters (handled by `ParameterNaming`) +- Function/method parameters (handled by `ParameterSnakeCase`) - Class properties (not enforced) - Reserved variables (`$this`, `$_GET`, `$_POST`, etc.) -### Error codes +### Error code -- `DrevOps.NamingConventions.LocalVariableNaming.NotSnakeCase` (when `format="snakeCase"`) -- `DrevOps.NamingConventions.LocalVariableNaming.NotCamelCase` (when `format="camelCase"`) +`DrevOps.NamingConventions.LocalVariableSnakeCase.NotSnakeCase` ### Ignore ```php -// phpcs:ignore DrevOps.NamingConventions.LocalVariableNaming.NotSnakeCase +// phpcs:ignore DrevOps.NamingConventions.LocalVariableSnakeCase.NotSnakeCase $myVariable = 'value'; ``` -## `ParameterNaming` +## `ParameterSnakeCase` -Enforces consistent naming convention for function/method parameters. +Enforces `snake_case` for function/method parameters. -**With `snakeCase` (default):** ```php function processOrder($order_id, $user_data) { // ✓ Valid -function processOrder($orderId, $userData) { // ✗ Error: NotSnakeCase -``` - -**With `camelCase`:** -```php -function processOrder($orderId, $userData) { // ✓ Valid -function processOrder($order_id, $user_data) { // ✗ Error: NotCamelCase +function processOrder($orderId, $userData) { // ✗ Error: ParameterNotSnakeCase ``` Excludes: @@ -148,15 +111,14 @@ Excludes: - Parameters in interface/abstract method declarations - Class properties (including promoted constructor properties) -### Error codes +### Error code -- `DrevOps.NamingConventions.ParameterNaming.NotSnakeCase` (when `format="snakeCase"`) -- `DrevOps.NamingConventions.ParameterNaming.NotCamelCase` (when `format="camelCase"`) +`DrevOps.NamingConventions.ParameterSnakeCase.NotSnakeCase` ### Ignore ```php -// phpcs:ignore DrevOps.NamingConventions.ParameterNaming.NotSnakeCase +// phpcs:ignore DrevOps.NamingConventions.ParameterSnakeCase.NotSnakeCase function process($legacyParam) {} ``` diff --git a/composer.json b/composer.json index 35e5558..1c09a2b 100644 --- a/composer.json +++ b/composer.json @@ -1,19 +1,8 @@ { "name": "drevops/phpcs-standard", - "description": "DrevOps PHP_CodeSniffer rules: enforce consistent naming (snakeCase or camelCase) for variables and parameters, PHPUnit data provider conventions.", + "description": "DrevOps PHP_CodeSniffer rules: enforce snake_case for variables and parameters.", "license": "GPL-2.0-or-later", "type": "phpcodesniffer-standard", - "keywords": [ - "phpcs", - "phpcodesniffer", - "standards", - "snakeCase", - "camelCase", - "naming-conventions", - "code-quality", - "phpunit", - "data-providers" - ], "authors": [ { "name": "Alex Skrypnyk", diff --git a/src/DrevOps/Sniffs/NamingConventions/AbstractVariableNamingSniff.php b/src/DrevOps/Sniffs/NamingConventions/AbstractSnakeCaseSniff.php similarity index 87% rename from src/DrevOps/Sniffs/NamingConventions/AbstractVariableNamingSniff.php rename to src/DrevOps/Sniffs/NamingConventions/AbstractSnakeCaseSniff.php index a106086..c53811b 100644 --- a/src/DrevOps/Sniffs/NamingConventions/AbstractVariableNamingSniff.php +++ b/src/DrevOps/Sniffs/NamingConventions/AbstractSnakeCaseSniff.php @@ -8,21 +8,12 @@ use PHP_CodeSniffer\Sniffs\Sniff; /** - * Abstract base class for variable naming convention sniffs. + * Abstract base class for snake_case variable naming sniffs. * * Provides shared functionality for validating and converting variable names - * to either snake_case or camelCase format based on configuration. + * to snake_case format. */ -abstract class AbstractVariableNamingSniff implements Sniff { - - /** - * The naming convention to enforce. - * - * Valid values: 'snakeCase', 'camelCase' - * - * @var string - */ - public $format = 'snakeCase'; +abstract class AbstractSnakeCaseSniff implements Sniff { /** * Reserved PHP variable names that should not be validated. @@ -77,36 +68,6 @@ protected function isSnakeCase(string $name): bool { return (bool) preg_match('/^[a-z][a-z0-9]*(_[a-z0-9]+)*$/', $name); } - /** - * Check if a variable name follows camelCase format. - * - * @param string $name - * Variable name (without $). - * - * @return bool - * TRUE if valid camelCase, FALSE otherwise. - */ - protected function isCamelCase(string $name): bool { - return (bool) preg_match('/^[a-z][a-zA-Z0-9]*$/', $name); - } - - /** - * Check if a variable name is valid for the configured format. - * - * @param string $name - * Variable name (without $). - * - * @return bool - * TRUE if valid for configured format, FALSE otherwise. - */ - protected function isValidFormat(string $name): bool { - return match ($this->format) { - 'snakeCase' => $this->isSnakeCase($name), - 'camelCase' => $this->isCamelCase($name), - default => throw new \RuntimeException('Invalid format: ' . $this->format), - }; - } - /** * Convert a variable name to snake_case. * @@ -135,44 +96,6 @@ protected function toSnakeCase(string $name): string { return $name; } - /** - * Convert a variable name to camelCase. - * - * @param string $name - * Variable name (without $). - * - * @return string - * Converted name in camelCase. - */ - protected function toCamelCase(string $name): string { - // Remove leading underscores. - $name = ltrim($name, '_'); - - // Split on underscores and capitalize each part except the first. - $parts = explode('_', $name); - $first = strtolower(array_shift($parts)); - $rest = array_map('ucfirst', array_map('strtolower', $parts)); - - return $first . implode('', $rest); - } - - /** - * Convert a variable name to the configured format. - * - * @param string $name - * Variable name (without $). - * - * @return string - * Converted name in the configured format. - */ - protected function toFormat(string $name): string { - return match ($this->format) { - 'snakeCase' => $this->toSnakeCase($name), - 'camelCase' => $this->toCamelCase($name), - default => throw new \RuntimeException('Invalid format: ' . $this->format), - }; - } - /** * Get all parameter names for a function/method. * diff --git a/src/DrevOps/Sniffs/NamingConventions/LocalVariableNamingSniff.php b/src/DrevOps/Sniffs/NamingConventions/LocalVariableSnakeCaseSniff.php similarity index 59% rename from src/DrevOps/Sniffs/NamingConventions/LocalVariableNamingSniff.php rename to src/DrevOps/Sniffs/NamingConventions/LocalVariableSnakeCaseSniff.php index 7ab91e6..531bc6c 100644 --- a/src/DrevOps/Sniffs/NamingConventions/LocalVariableNamingSniff.php +++ b/src/DrevOps/Sniffs/NamingConventions/LocalVariableSnakeCaseSniff.php @@ -7,24 +7,18 @@ use PHP_CodeSniffer\Files\File; /** - * Enforces consistent naming convention for local variables. + * Enforces snake_case naming for local variables. * - * This sniff checks that local variables use the configured naming format - * (snakeCase or camelCase). Function/method parameters and class properties - * are excluded. + * This sniff checks that local variables use snake_case format. + * Function/method parameters and class properties are excluded. */ -final class LocalVariableNamingSniff extends AbstractVariableNamingSniff { +final class LocalVariableSnakeCaseSniff extends AbstractSnakeCaseSniff { /** * Error code for non-snake_case variables. */ public const CODE_VARIABLE_NOT_SNAKE_CASE = 'NotSnakeCase'; - /** - * Error code for non-camelCase variables. - */ - public const CODE_VARIABLE_NOT_CAMEL_CASE = 'NotCamelCase'; - /** * {@inheritdoc} */ @@ -48,26 +42,21 @@ public function process(File $phpcsFile, $stackPtr): void { } // Skip parameters (both declaration and usage). - // Handled by ParameterNamingSniff. + // Handled by ParameterSnakeCaseSniff. if ($this->isParameter($phpcsFile, $stackPtr, TRUE)) { return; } - // Check if the variable name follows the configured format. - if (!$this->isValidFormat($var_name)) { - $suggestion = $this->toFormat($var_name); - $error = 'Variable "$%s" is not in %s format; try "$%s"'; - $data = [$var_name, $this->format, $suggestion]; - - // Determine the error code based on the configured format. - $error_code = ($this->format === 'snakeCase') ? - self::CODE_VARIABLE_NOT_SNAKE_CASE : - self::CODE_VARIABLE_NOT_CAMEL_CASE; + // Check if the variable name is in snake_case format. + if (!$this->isSnakeCase($var_name)) { + $suggestion = $this->toSnakeCase($var_name); + $error = 'Variable "$%s" is not in snake_case format; try "$%s"'; + $data = [$var_name, $suggestion]; $fix = $phpcsFile->addFixableError( $error, $stackPtr, - $error_code, + self::CODE_VARIABLE_NOT_SNAKE_CASE, $data ); diff --git a/src/DrevOps/Sniffs/NamingConventions/ParameterNamingSniff.php b/src/DrevOps/Sniffs/NamingConventions/ParameterSnakeCaseSniff.php similarity index 82% rename from src/DrevOps/Sniffs/NamingConventions/ParameterNamingSniff.php rename to src/DrevOps/Sniffs/NamingConventions/ParameterSnakeCaseSniff.php index 5ac689f..eec7265 100644 --- a/src/DrevOps/Sniffs/NamingConventions/ParameterNamingSniff.php +++ b/src/DrevOps/Sniffs/NamingConventions/ParameterSnakeCaseSniff.php @@ -7,25 +7,19 @@ use PHP_CodeSniffer\Files\File; /** - * Enforces consistent naming convention for function/method parameters. + * Enforces snake_case naming for function/method parameters. * - * This sniff checks that function and method parameters use the configured - * naming format (snakeCase or camelCase). Local variables and class properties - * are excluded. Parameters inherited from interfaces/parent classes are also - * excluded. + * This sniff checks that function and method parameters use snake_case format. + * Local variables and class properties are excluded. + * Parameters inherited from interfaces/parent classes are also excluded. */ -final class ParameterNamingSniff extends AbstractVariableNamingSniff { +final class ParameterSnakeCaseSniff extends AbstractSnakeCaseSniff { /** * Error code for non-snake_case parameters. */ public const CODE_PARAMETER_NOT_SNAKE_CASE = 'NotSnakeCase'; - /** - * Error code for non-camelCase parameters. - */ - public const CODE_PARAMETER_NOT_CAMEL_CASE = 'NotCamelCase'; - /** * {@inheritdoc} */ @@ -39,7 +33,7 @@ public function process(File $phpcsFile, $stackPtr): void { } // Only process parameters (declaration only, not usage in body). - // Local variables handled by LocalVariableNamingSniff. + // Local variables handled by LocalVariableSnakeCaseSniff. if (!$this->isParameter($phpcsFile, $stackPtr, FALSE)) { return; } @@ -50,21 +44,16 @@ public function process(File $phpcsFile, $stackPtr): void { return; } - // Check if the variable name follows the configured format. - if (!$this->isValidFormat($var_name)) { - $suggestion = $this->toFormat($var_name); - $error = 'Variable "$%s" is not in %s format; try "$%s"'; - $data = [$var_name, $this->format, $suggestion]; - - // Determine the error code based on the configured format. - $error_code = ($this->format === 'snakeCase') ? - self::CODE_PARAMETER_NOT_SNAKE_CASE : - self::CODE_PARAMETER_NOT_CAMEL_CASE; + // Check if the variable name is in snake_case format. + if (!$this->isSnakeCase($var_name)) { + $suggestion = $this->toSnakeCase($var_name); + $error = 'Variable "$%s" is not in snake_case format; try "$%s"'; + $data = [$var_name, $suggestion]; $fix = $phpcsFile->addFixableError( $error, $stackPtr, - $error_code, + self::CODE_PARAMETER_NOT_SNAKE_CASE, $data ); diff --git a/src/DrevOps/ruleset.xml b/src/DrevOps/ruleset.xml index dcbefe5..016e97e 100644 --- a/src/DrevOps/ruleset.xml +++ b/src/DrevOps/ruleset.xml @@ -2,17 +2,11 @@ DrevOps PHP_CodeSniffer standard. - - - - - + + - - - - - + + diff --git a/tests/Functional/LocalVariableNamingSniffFunctionalTest.php b/tests/Functional/LocalVariableSnakeCaseSniffFunctionalTest.php similarity index 57% rename from tests/Functional/LocalVariableNamingSniffFunctionalTest.php rename to tests/Functional/LocalVariableSnakeCaseSniffFunctionalTest.php index ff6f8b0..0165646 100644 --- a/tests/Functional/LocalVariableNamingSniffFunctionalTest.php +++ b/tests/Functional/LocalVariableSnakeCaseSniffFunctionalTest.php @@ -8,18 +8,18 @@ use PHPUnit\Framework\Attributes\Group; /** - * Functional integration test for LocalVariableNamingSniff. + * Functional integration test for LocalVariableSnakeCaseSniff. * * This tests the sniff by actually running phpcs as an external command, * which is the most reliable way to test PHPCS sniffs. */ #[CoversNothing] -class LocalVariableNamingSniffFunctionalTest extends FunctionalTestCase { +class LocalVariableSnakeCaseSniffFunctionalTest extends FunctionalTestCase { /** * {@inheritdoc} */ - protected string $sniffSource = 'DrevOps.NamingConventions.LocalVariableNaming'; + protected string $sniffSource = 'DrevOps.NamingConventions.LocalVariableSnakeCase'; #[Group('smoke')] public function testSmoke(): void { @@ -31,38 +31,38 @@ public function testSniffDetectsLocalVariableViolations(): void { static::$fixtures . DIRECTORY_SEPARATOR . 'VariableNaming.php', [ [ - 'message' => 'Variable "$invalidVariable" is not in snakeCase format; try "$invalid_variable"', - 'source' => 'DrevOps.NamingConventions.LocalVariableNaming.NotSnakeCase', + 'message' => 'Variable "$invalidVariable" is not in snake_case format; try "$invalid_variable"', + 'source' => 'DrevOps.NamingConventions.LocalVariableSnakeCase.NotSnakeCase', 'fixable' => TRUE, ], [ - 'message' => 'Variable "$anotherInvalid" is not in snakeCase format; try "$another_invalid"', - 'source' => 'DrevOps.NamingConventions.LocalVariableNaming.NotSnakeCase', + 'message' => 'Variable "$anotherInvalid" is not in snake_case format; try "$another_invalid"', + 'source' => 'DrevOps.NamingConventions.LocalVariableSnakeCase.NotSnakeCase', 'fixable' => TRUE, ], [ - 'message' => 'Variable "$testCamelCase" is not in snakeCase format; try "$test_camel_case"', - 'source' => 'DrevOps.NamingConventions.LocalVariableNaming.NotSnakeCase', + 'message' => 'Variable "$testCamelCase" is not in snake_case format; try "$test_camel_case"', + 'source' => 'DrevOps.NamingConventions.LocalVariableSnakeCase.NotSnakeCase', 'fixable' => TRUE, ], [ - 'message' => 'Variable "$invalidVar" is not in snakeCase format; try "$invalid_var"', - 'source' => 'DrevOps.NamingConventions.LocalVariableNaming.NotSnakeCase', + 'message' => 'Variable "$invalidVar" is not in snake_case format; try "$invalid_var"', + 'source' => 'DrevOps.NamingConventions.LocalVariableSnakeCase.NotSnakeCase', 'fixable' => TRUE, ], [ - 'message' => 'Variable "$invalidParam" is not in snakeCase format; try "$invalid_param"', - 'source' => 'DrevOps.NamingConventions.LocalVariableNaming.NotSnakeCase', + 'message' => 'Variable "$invalidParam" is not in snake_case format; try "$invalid_param"', + 'source' => 'DrevOps.NamingConventions.LocalVariableSnakeCase.NotSnakeCase', 'fixable' => TRUE, ], [ - 'message' => 'Variable "$localVar" is not in snakeCase format; try "$local_var"', - 'source' => 'DrevOps.NamingConventions.LocalVariableNaming.NotSnakeCase', + 'message' => 'Variable "$localVar" is not in snake_case format; try "$local_var"', + 'source' => 'DrevOps.NamingConventions.LocalVariableSnakeCase.NotSnakeCase', 'fixable' => TRUE, ], [ - 'message' => 'Variable "$invalidVar" is not in snakeCase format; try "$invalid_var"', - 'source' => 'DrevOps.NamingConventions.LocalVariableNaming.NotSnakeCase', + 'message' => 'Variable "$invalidVar" is not in snake_case format; try "$invalid_var"', + 'source' => 'DrevOps.NamingConventions.LocalVariableSnakeCase.NotSnakeCase', 'fixable' => TRUE, ], ] @@ -77,8 +77,8 @@ public function testAttributedPropertiesAreNotFlagged(): void { static::$fixtures . DIRECTORY_SEPARATOR . 'AttributedProperties.php', [ [ - 'message' => 'Variable "$invalidLocalVar" is not in snakeCase format; try "$invalid_local_var"', - 'source' => 'DrevOps.NamingConventions.LocalVariableNaming.NotSnakeCase', + 'message' => 'Variable "$invalidLocalVar" is not in snake_case format; try "$invalid_local_var"', + 'source' => 'DrevOps.NamingConventions.LocalVariableSnakeCase.NotSnakeCase', 'fixable' => TRUE, ], ] @@ -93,13 +93,13 @@ public function testOnlyLocalVariablesAreFlagged(): void { static::$fixtures . DIRECTORY_SEPARATOR . 'InheritedParameters.php', [ [ - 'message' => 'Variable "$localInvalidCamelCase" is not in snakeCase format; try "$local_invalid_camel_case"', - 'source' => 'DrevOps.NamingConventions.LocalVariableNaming.NotSnakeCase', + 'message' => 'Variable "$localInvalidCamelCase" is not in snake_case format; try "$local_invalid_camel_case"', + 'source' => 'DrevOps.NamingConventions.LocalVariableSnakeCase.NotSnakeCase', 'fixable' => TRUE, ], [ - 'message' => 'Variable "$localInvalidCamelCase" is not in snakeCase format; try "$local_invalid_camel_case"', - 'source' => 'DrevOps.NamingConventions.LocalVariableNaming.NotSnakeCase', + 'message' => 'Variable "$localInvalidCamelCase" is not in snake_case format; try "$local_invalid_camel_case"', + 'source' => 'DrevOps.NamingConventions.LocalVariableSnakeCase.NotSnakeCase', 'fixable' => TRUE, ], ] diff --git a/tests/Functional/ParameterNamingSniffFunctionalTest.php b/tests/Functional/ParameterSnakeCaseSniffFunctionalTest.php similarity index 83% rename from tests/Functional/ParameterNamingSniffFunctionalTest.php rename to tests/Functional/ParameterSnakeCaseSniffFunctionalTest.php index e58cb5e..b1371fa 100644 --- a/tests/Functional/ParameterNamingSniffFunctionalTest.php +++ b/tests/Functional/ParameterSnakeCaseSniffFunctionalTest.php @@ -8,18 +8,18 @@ use PHPUnit\Framework\Attributes\Group; /** - * Functional integration test for ParameterNamingSniff. + * Functional integration test for ParameterSnakeCaseSniff. * * This tests the sniff by actually running phpcs as an external command, * which is the most reliable way to test PHPCS sniffs. */ #[CoversNothing] -class ParameterNamingSniffFunctionalTest extends FunctionalTestCase { +class ParameterSnakeCaseSniffFunctionalTest extends FunctionalTestCase { /** * {@inheritdoc} */ - protected string $sniffSource = 'DrevOps.NamingConventions.ParameterNaming'; + protected string $sniffSource = 'DrevOps.NamingConventions.ParameterSnakeCase'; #[Group('smoke')] public function testSmoke(): void { @@ -31,18 +31,18 @@ public function testSniffDetectsParameterViolations(): void { static::$fixtures . DIRECTORY_SEPARATOR . 'VariableNaming.php', [ [ - 'message' => 'Variable "$invalidParam" is not in snakeCase format; try "$invalid_param"', - 'source' => 'DrevOps.NamingConventions.ParameterNaming.NotSnakeCase', + 'message' => 'Variable "$invalidParam" is not in snake_case format; try "$invalid_param"', + 'source' => 'DrevOps.NamingConventions.ParameterSnakeCase.NotSnakeCase', 'fixable' => TRUE, ], [ - 'message' => 'Variable "$invalidParam" is not in snakeCase format; try "$invalid_param"', - 'source' => 'DrevOps.NamingConventions.ParameterNaming.NotSnakeCase', + 'message' => 'Variable "$invalidParam" is not in snake_case format; try "$invalid_param"', + 'source' => 'DrevOps.NamingConventions.ParameterSnakeCase.NotSnakeCase', 'fixable' => TRUE, ], [ - 'message' => 'Variable "$invalidParam" is not in snakeCase format; try "$invalid_param"', - 'source' => 'DrevOps.NamingConventions.ParameterNaming.NotSnakeCase', + 'message' => 'Variable "$invalidParam" is not in snake_case format; try "$invalid_param"', + 'source' => 'DrevOps.NamingConventions.ParameterSnakeCase.NotSnakeCase', 'fixable' => TRUE, ], ] @@ -57,13 +57,13 @@ public function testInheritedParametersAreNotFlagged(): void { static::$fixtures . DIRECTORY_SEPARATOR . 'InheritedParameters.php', [ [ - 'message' => 'Variable "$invalidNonInheritedParamOne" is not in snakeCase format; try "$invalid_non_inherited_param_one"', - 'source' => 'DrevOps.NamingConventions.ParameterNaming.NotSnakeCase', + 'message' => 'Variable "$invalidNonInheritedParamOne" is not in snake_case format; try "$invalid_non_inherited_param_one"', + 'source' => 'DrevOps.NamingConventions.ParameterSnakeCase.NotSnakeCase', 'fixable' => TRUE, ], [ - 'message' => 'Variable "$invalidNonInheritedParamTwo" is not in snakeCase format; try "$invalid_non_inherited_param_two"', - 'source' => 'DrevOps.NamingConventions.ParameterNaming.NotSnakeCase', + 'message' => 'Variable "$invalidNonInheritedParamTwo" is not in snake_case format; try "$invalid_non_inherited_param_two"', + 'source' => 'DrevOps.NamingConventions.ParameterSnakeCase.NotSnakeCase', 'fixable' => TRUE, ], ] @@ -97,7 +97,7 @@ public function testPhpcbfFixesDocblockParams(): void { $this->processRun( $phpcbf_bin, - ['--standard=DrevOps', '--sniffs=DrevOps.NamingConventions.ParameterNaming', '-q', $temp_file], + ['--standard=DrevOps', '--sniffs=DrevOps.NamingConventions.ParameterSnakeCase', '-q', $temp_file], timeout: 120 ); @@ -115,7 +115,7 @@ public function testPhpcbfFixesDocblockParams(): void { // Verify old parameter names are gone from signatures and docblocks. // Note: Parameter usages in method bodies are NOT fixed by this sniff - - // that's the job of LocalVariableNamingSniff. + // that's the job of LocalVariableSnakeCaseSniff. $this->assertStringNotContainsString('function methodWithDocblock(string $invalidParam', $fixed_content, 'Old parameter name should not exist in signature'); $this->assertStringNotContainsString('@param string $invalidParam', $fixed_content, 'Old parameter name should not exist in docblock'); $this->assertStringNotContainsString('@param int $anotherInvalid', $fixed_content, 'Old parameter name should not exist in docblock'); diff --git a/tests/Unit/AbstractVariableNamingSniffTest.php b/tests/Unit/AbstractVariableSnakeCaseSniffTest.php similarity index 67% rename from tests/Unit/AbstractVariableNamingSniffTest.php rename to tests/Unit/AbstractVariableSnakeCaseSniffTest.php index 1b65f00..c1c63d2 100644 --- a/tests/Unit/AbstractVariableNamingSniffTest.php +++ b/tests/Unit/AbstractVariableSnakeCaseSniffTest.php @@ -4,20 +4,20 @@ namespace DrevOps\PhpcsStandard\Tests\Unit; -use DrevOps\Sniffs\NamingConventions\AbstractVariableNamingSniff; -use DrevOps\Sniffs\NamingConventions\LocalVariableNamingSniff; -use DrevOps\Sniffs\NamingConventions\ParameterNamingSniff; +use DrevOps\Sniffs\NamingConventions\AbstractSnakeCaseSniff; +use DrevOps\Sniffs\NamingConventions\LocalVariableSnakeCaseSniff; +use DrevOps\Sniffs\NamingConventions\ParameterSnakeCaseSniff; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\DataProvider; /** - * Tests for AbstractVariableNamingSniff. + * Tests for AbstractSnakeCaseSniff. * * Tests all shared methods in the abstract base class using - * LocalVariableNamingSniff as the concrete implementation. + * LocalVariableSnakeCaseSniff as the concrete implementation. */ -#[CoversClass(AbstractVariableNamingSniff::class)] -class AbstractVariableNamingSniffTest extends UnitTestCase { +#[CoversClass(AbstractSnakeCaseSniff::class)] +class AbstractVariableSnakeCaseSniffTest extends UnitTestCase { /** * Test snake_case detection. @@ -29,7 +29,7 @@ class AbstractVariableNamingSniffTest extends UnitTestCase { */ #[DataProvider('dataProviderSnakeCaseDetection')] public function testSnakeCaseDetection(string $name, bool $expected): void { - $sniff = new LocalVariableNamingSniff(); + $sniff = new LocalVariableSnakeCaseSniff(); $reflection = new \ReflectionClass($sniff); $method = $reflection->getMethod('isSnakeCase'); @@ -71,7 +71,7 @@ public static function dataProviderSnakeCaseDetection(): array { */ #[DataProvider('providerToSnakeCase')] public function testToSnakeCase(string $input, string $expected): void { - $sniff = new LocalVariableNamingSniff(); + $sniff = new LocalVariableSnakeCaseSniff(); $reflection = new \ReflectionClass($sniff); $method = $reflection->getMethod('toSnakeCase'); @@ -107,7 +107,7 @@ public static function providerToSnakeCase(): array { */ #[DataProvider('providerReservedVariables')] public function testReservedVariables(string $name, bool $expected): void { - $sniff = new LocalVariableNamingSniff(); + $sniff = new LocalVariableSnakeCaseSniff(); $reflection = new \ReflectionClass($sniff); $method = $reflection->getMethod('isReserved'); @@ -144,7 +144,7 @@ public static function providerReservedVariables(): array { * Test register method. */ public function testRegister(): void { - $sniff = new LocalVariableNamingSniff(); + $sniff = new LocalVariableSnakeCaseSniff(); $tokens = $sniff->register(); $this->assertContains(T_VARIABLE, $tokens); @@ -162,7 +162,7 @@ public function testRegister(): void { public function testGetParameterNames(string $code, array $expected_params): void { $file = $this->processCode($code); $function_ptr = $this->findFunctionToken($file); - $sniff = new LocalVariableNamingSniff(); + $sniff = new LocalVariableSnakeCaseSniff(); $reflection = new \ReflectionClass($sniff); $method = $reflection->getMethod('getParameterNames'); $result = $method->invoke($sniff, $file, $function_ptr); @@ -211,7 +211,7 @@ public static function providerGetParameterNames(): array { public function testIsProperty(string $code, string $variable_name, bool $expected): void { $file = $this->processCode($code); $variable_ptr = $this->findVariableToken($file, $variable_name); - $sniff = new LocalVariableNamingSniff(); + $sniff = new LocalVariableSnakeCaseSniff(); $reflection = new \ReflectionClass($sniff); $method = $reflection->getMethod('isProperty'); $result = $method->invoke($sniff, $file, $variable_ptr); @@ -278,7 +278,7 @@ public static function providerIsProperty(): array { public function testIsPromotedProperty(string $code, string $variable_name, bool $expected): void { $file = $this->processCode($code); $variable_ptr = $this->findVariableToken($file, $variable_name); - $sniff = new LocalVariableNamingSniff(); + $sniff = new LocalVariableSnakeCaseSniff(); $reflection = new \ReflectionClass($sniff); $method = $reflection->getMethod('isPromotedProperty'); $result = $method->invoke($sniff, $file, $variable_ptr); @@ -345,7 +345,7 @@ public static function providerIsPromotedProperty(): array { public function testIsInheritedParameter(string $code, string $variable_name, bool $expected): void { $file = $this->processCode($code); $variable_ptr = $this->findVariableToken($file, $variable_name); - $sniff = new ParameterNamingSniff(); + $sniff = new ParameterSnakeCaseSniff(); $reflection = new \ReflectionClass($sniff); $method = $reflection->getMethod('isInheritedParameter'); $result = $method->invoke($sniff, $file, $variable_ptr); @@ -422,7 +422,7 @@ public static function providerIsInheritedParameter(): array { public function testIsStaticPropertyAccess(string $code, string $variable_name, bool $expected): void { $file = $this->processCode($code); $variable_ptr = $this->findVariableToken($file, $variable_name); - $sniff = new LocalVariableNamingSniff(); + $sniff = new LocalVariableSnakeCaseSniff(); $reflection = new \ReflectionClass($sniff); $method = $reflection->getMethod('isStaticPropertyAccess'); $result = $method->invoke($sniff, $file, $variable_ptr); @@ -475,182 +475,4 @@ public static function providerIsStaticPropertyAccess(): array { ]; } - /** - * Test camelCase detection. - * - * @param string $name - * The variable name to test. - * @param bool $expected - * Expected result. - */ - #[DataProvider('dataProviderCamelCaseDetection')] - public function testCamelCaseDetection(string $name, bool $expected): void { - $sniff = new LocalVariableNamingSniff(); - $reflection = new \ReflectionClass($sniff); - $method = $reflection->getMethod('isCamelCase'); - - $result = $method->invoke($sniff, $name); - $this->assertSame($expected, $result, 'Failed for: ' . $name); - } - - /** - * Data provider for camelCase detection tests. - * - * @return array> - * Test cases. - */ - public static function dataProviderCamelCaseDetection(): array { - return [ - 'valid_single_word' => ['test', TRUE], - 'valid_camelCase' => ['testVariable', TRUE], - 'valid_with_number' => ['test123', TRUE], - 'valid_camelCase_with_number' => ['testVariable123', TRUE], - 'valid_long_camelCase' => ['testLongVariableName', TRUE], - 'invalid_snake_case' => ['test_variable', FALSE], - 'invalid_PascalCase' => ['TestVariable', FALSE], - 'invalid_uppercase' => ['TEST', FALSE], - 'invalid_starting_uppercase' => ['Test', FALSE], - 'invalid_with_underscore' => ['test_var', FALSE], - 'invalid_leading_underscore' => ['_test', FALSE], - ]; - } - - /** - * Test camelCase conversion. - * - * @param string $input - * The input name. - * @param string $expected - * Expected output. - */ - #[DataProvider('providerToCamelCase')] - public function testToCamelCase(string $input, string $expected): void { - $sniff = new LocalVariableNamingSniff(); - $reflection = new \ReflectionClass($sniff); - $method = $reflection->getMethod('toCamelCase'); - - $result = $method->invoke($sniff, $input); - $this->assertSame($expected, $result); - } - - /** - * Data provider for toCamelCase conversion tests. - * - * @return array> - * Test cases. - */ - public static function providerToCamelCase(): array { - return [ - 'snake_case' => ['test_variable', 'testVariable'], - 'PascalCase' => ['TestVariable', 'testvariable'], - 'already_camel' => ['testVariable', 'testvariable'], - 'with_numbers' => ['test_123_variable', 'test123Variable'], - 'multiple_underscores' => ['test__variable', 'testVariable'], - 'leading_underscore' => ['_test_variable', 'testVariable'], - 'single_word' => ['test', 'test'], - ]; - } - - /** - * Test isValidFormat() method. - * - * @param string $format - * The format to configure. - * @param string $name - * The variable name to test. - * @param bool $expected - * Expected result. - */ - #[DataProvider('providerIsValidFormat')] - public function testIsValidFormat(string $format, string $name, bool $expected): void { - $sniff = new LocalVariableNamingSniff(); - $sniff->format = $format; - $reflection = new \ReflectionClass($sniff); - $method = $reflection->getMethod('isValidFormat'); - - $result = $method->invoke($sniff, $name); - $this->assertSame($expected, $result); - } - - /** - * Data provider for isValidFormat tests. - * - * @return array> - * Test cases. - */ - public static function providerIsValidFormat(): array { - return [ - 'snakeCase_valid_snake' => ['snakeCase', 'test_variable', TRUE], - 'snakeCase_invalid_camel' => ['snakeCase', 'testVariable', FALSE], - 'camelCase_valid_camel' => ['camelCase', 'testVariable', TRUE], - 'camelCase_invalid_snake' => ['camelCase', 'test_variable', FALSE], - 'snakeCase_single_word' => ['snakeCase', 'test', TRUE], - 'camelCase_single_word' => ['camelCase', 'test', TRUE], - ]; - } - - /** - * Test toFormat() method. - * - * @param string $format - * The format to configure. - * @param string $input - * The input name. - * @param string $expected - * Expected output. - */ - #[DataProvider('providerToFormat')] - public function testToFormat(string $format, string $input, string $expected): void { - $sniff = new LocalVariableNamingSniff(); - $sniff->format = $format; - $reflection = new \ReflectionClass($sniff); - $method = $reflection->getMethod('toFormat'); - - $result = $method->invoke($sniff, $input); - $this->assertSame($expected, $result); - } - - /** - * Data provider for toFormat tests. - * - * @return array> - * Test cases. - */ - public static function providerToFormat(): array { - return [ - 'snakeCase_from_camel' => ['snakeCase', 'testVariable', 'test_variable'], - 'snakeCase_from_snake' => ['snakeCase', 'test_variable', 'test_variable'], - 'camelCase_from_snake' => ['camelCase', 'test_variable', 'testVariable'], - 'camelCase_from_camel' => ['camelCase', 'testVariable', 'testvariable'], - ]; - } - - /** - * Test that isValidFormat() throws exception for invalid format. - */ - public function testIsValidFormatThrowsExceptionForInvalidFormat(): void { - $sniff = new LocalVariableNamingSniff(); - $sniff->format = 'invalidFormat'; - $reflection = new \ReflectionClass($sniff); - $method = $reflection->getMethod('isValidFormat'); - - $this->expectException(\RuntimeException::class); - $this->expectExceptionMessage('Invalid format: invalidFormat'); - $method->invoke($sniff, 'test'); - } - - /** - * Test that toFormat() throws exception for invalid format. - */ - public function testToFormatThrowsExceptionForInvalidFormat(): void { - $sniff = new LocalVariableNamingSniff(); - $sniff->format = 'invalidFormat'; - $reflection = new \ReflectionClass($sniff); - $method = $reflection->getMethod('toFormat'); - - $this->expectException(\RuntimeException::class); - $this->expectExceptionMessage('Invalid format: invalidFormat'); - $method->invoke($sniff, 'test'); - } - } diff --git a/tests/Unit/LocalVariableNamingSniffTest.php b/tests/Unit/LocalVariableSnakeCaseSniffTest.php similarity index 52% rename from tests/Unit/LocalVariableNamingSniffTest.php rename to tests/Unit/LocalVariableSnakeCaseSniffTest.php index 3f7f48f..86fec62 100644 --- a/tests/Unit/LocalVariableNamingSniffTest.php +++ b/tests/Unit/LocalVariableSnakeCaseSniffTest.php @@ -4,20 +4,19 @@ namespace DrevOps\PhpcsStandard\Tests\Unit; -use PHP_CodeSniffer\Config; use PHP_CodeSniffer\Ruleset; -use DrevOps\Sniffs\NamingConventions\LocalVariableNamingSniff; +use DrevOps\Sniffs\NamingConventions\LocalVariableSnakeCaseSniff; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\DataProvider; /** - * Tests for LocalVariableNamingSniff. + * Tests for LocalVariableSnakeCaseSniff. * * Tests only sniff-specific logic. Abstract base class methods are tested - * in AbstractVariableNamingSniffTest. + * in AbstractVariableSnakeCaseSniffTest. */ -#[CoversClass(LocalVariableNamingSniff::class)] -class LocalVariableNamingSniffTest extends UnitTestCase { +#[CoversClass(LocalVariableSnakeCaseSniff::class)] +class LocalVariableSnakeCaseSniffTest extends UnitTestCase { /** * {@inheritdoc} @@ -25,17 +24,16 @@ class LocalVariableNamingSniffTest extends UnitTestCase { #[\Override] protected function setUp(): void { parent::setUp(); - // Configure to run only LocalVariableNaming sniff. - $this->config->sniffs = ['DrevOps.NamingConventions.LocalVariableNaming']; + // Configure to run only LocalVariableSnakeCase sniff. + $this->config->sniffs = ['DrevOps.NamingConventions.LocalVariableSnakeCase']; $this->ruleset = new Ruleset($this->config); } /** - * Test error code constants. + * Test error code constant. */ public function testErrorCodeConstant(): void { - $this->assertSame('NotSnakeCase', LocalVariableNamingSniff::CODE_VARIABLE_NOT_SNAKE_CASE); - $this->assertSame('NotCamelCase', LocalVariableNamingSniff::CODE_VARIABLE_NOT_CAMEL_CASE); + $this->assertSame('NotSnakeCase', LocalVariableSnakeCaseSniff::CODE_VARIABLE_NOT_SNAKE_CASE); } /** @@ -122,82 +120,4 @@ public static function dataProviderProcess(): array { ]; } - /** - * Test process method with camelCase format. - * - * @param string $code - * PHP code to test. - * @param bool $should_have_errors - * Whether errors should be detected. - */ - #[DataProvider('dataProviderProcessWithCamelCaseFormat')] - public function testProcessWithCamelCaseFormat(string $code, bool $should_have_errors): void { - // Create a new config with camelCase format property. - $config = new Config(); - $config->standards = ['DrevOps']; - $config->sniffs = ['DrevOps.NamingConventions.LocalVariableNaming']; - - // Create temporary ruleset XML with property configuration. - $ruleset_xml = ' - - - - - - -'; - - $ruleset_file = tempnam(sys_get_temp_dir(), 'phpcs_ruleset_'); - file_put_contents($ruleset_file, $ruleset_xml); - - try { - $config->standards = [$ruleset_file]; - $this->ruleset = new Ruleset($config); - - $file = $this->processCode($code); - $errors = $file->getErrors(); - - if ($should_have_errors) { - $this->assertNotEmpty($errors); - } - else { - $this->assertEmpty($errors); - } - } - finally { - unlink($ruleset_file); - } - } - - /** - * Data provider for camelCase format tests. - * - * @return array> - * Test cases. - */ - public static function dataProviderProcessWithCamelCaseFormat(): array { - return [ - 'valid_camel_case_variable' => [ - ' [ - ' [ - ' [ - ' [ - 'config->sniffs = ['DrevOps.NamingConventions.ParameterNaming']; + // Configure to run only ParameterSnakeCase sniff. + $this->config->sniffs = ['DrevOps.NamingConventions.ParameterSnakeCase']; $this->ruleset = new Ruleset($this->config); } @@ -34,18 +33,17 @@ protected function setUp(): void { * Test that the sniff registers the correct token types. */ public function testRegister(): void { - $sniff = new ParameterNamingSniff(); + $sniff = new ParameterSnakeCaseSniff(); $tokens = $sniff->register(); $this->assertContains(T_VARIABLE, $tokens); } /** - * Test error code constants. + * Test error code constant. */ public function testErrorCodeConstant(): void { - $this->assertSame('NotSnakeCase', ParameterNamingSniff::CODE_PARAMETER_NOT_SNAKE_CASE); - $this->assertSame('NotCamelCase', ParameterNamingSniff::CODE_PARAMETER_NOT_CAMEL_CASE); + $this->assertSame('NotSnakeCase', ParameterSnakeCaseSniff::CODE_PARAMETER_NOT_SNAKE_CASE); } /** @@ -116,84 +114,6 @@ public static function dataProviderProcess(): array { ]; } - /** - * Test process method with camelCase format. - * - * @param string $code - * PHP code to test. - * @param bool $should_have_errors - * Whether errors should be detected. - */ - #[DataProvider('dataProviderProcessWithCamelCaseFormat')] - public function testProcessWithCamelCaseFormat(string $code, bool $should_have_errors): void { - // Create a new config with camelCase format property. - $config = new Config(); - $config->standards = ['DrevOps']; - $config->sniffs = ['DrevOps.NamingConventions.ParameterNaming']; - - // Create temporary ruleset XML with property configuration. - $ruleset_xml = ' - - - - - - -'; - - $ruleset_file = tempnam(sys_get_temp_dir(), 'phpcs_ruleset_'); - file_put_contents($ruleset_file, $ruleset_xml); - - try { - $config->standards = [$ruleset_file]; - $this->ruleset = new Ruleset($config); - - $file = $this->processCode($code); - $errors = $file->getErrors(); - - if ($should_have_errors) { - $this->assertNotEmpty($errors); - } - else { - $this->assertEmpty($errors); - } - } - finally { - unlink($ruleset_file); - } - } - - /** - * Data provider for camelCase format tests. - * - * @return array> - * Test cases. - */ - public static function dataProviderProcessWithCamelCaseFormat(): array { - return [ - 'valid_camel_case_parameter' => [ - ' [ - ' [ - ' [ - ' [ - 'processCode($code); - $sniff = new ParameterNamingSniff(); + $sniff = new ParameterSnakeCaseSniff(); // Use reflection to access the private method. $reflection = new \ReflectionClass($sniff);