Skip to content

Releases: drevops/phpcs-standard

0.7.0

12 Mar 23:44
caee870

Choose a tag to compare

What's new since 0.6.2

Full Changelog: 0.6.2...0.7.0

@AlexSkrypnyk

0.6.2

18 Dec 04:23

Choose a tag to compare

What's new since 0.6.1

Full Changelog: 0.6.1...0.6.2

@AlexSkrypnyk

0.6.1

16 Dec 22:47

Choose a tag to compare

What's new since 0.6.0

  • [#13] Fixed nullable class properties incorrectly triggering LocalVariableNaming.NotSnakeCase. @AlexSkrypnyk (#14)

Full Changelog: 0.6.0...0.6.1

@AlexSkrypnyk

0.6.0

24 Nov 12:40

Choose a tag to compare

What's new since 0.5.0

✨ Key Changes

Allow to specify snake or camel case format for local variables and function parameters.

📝 Configuration Examples

Default Behavior (snake_case)

<rule ref="DrevOps.NamingConventions.LocalVariableNaming"/>
<rule ref="DrevOps.NamingConventions.ParameterNaming"/>

Configure for camelCase

<rule ref="DrevOps.NamingConventions.LocalVariableNaming">
    <properties>
        <property name="format" value="camelCase"/>
    </properties>
</rule>

<rule ref="DrevOps.NamingConventions.ParameterNaming">
    <properties>
        <property name="format" value="camelCase"/>
    </properties>
</rule>

🔧 Migration Guide

Update XML Configuration

- <rule ref="DrevOps.NamingConventions.LocalVariableSnakeCase"/>
+ <rule ref="DrevOps.NamingConventions.LocalVariableNaming"/>

- <rule ref="DrevOps.NamingConventions.ParameterSnakeCase"/>
+ <rule ref="DrevOps.NamingConventions.ParameterNaming"/>

Update Inline Suppressions

- // phpcs:ignore DrevOps.NamingConventions.LocalVariableSnakeCase.NotSnakeCase
+ // phpcs:ignore DrevOps.NamingConventions.LocalVariableNaming.NotSnakeCase

- // phpcs:ignore DrevOps.NamingConventions.ParameterSnakeCase.NotSnakeCase
+ // phpcs:ignore DrevOps.NamingConventions.ParameterNaming.NotSnakeCase

✅ Backward Compatibility

  • Default behavior unchanged: snake_case remains the default format
  • Existing configurations work: Rules auto-upgrade if using DrevOps ruleset
  • No code changes required: Only if using custom configurations or direct class references

Changelog

  • Refactored case sniffs to allow choosing snake or camel case. @AlexSkrypnyk (#12)
  • Updated own reference to the standard and fixed violations. @AlexSkrypnyk (#9)
  • Fixed snake_case not being updated in the docblocks. @AlexSkrypnyk (#8)

Full Changelog: 0.5.0...0.6.0

@AlexSkrypnyk

0.5.0

23 Nov 06:17
094fa98

Choose a tag to compare

What's new since 0.4.0

DrevOps.TestingPractices.DataProviderPrefix
DrevOps.TestingPractices.DataProviderMatchesTestName
DrevOps.TestingPractices.DataProviderOrder

DrevOps.TestingPractices.DataProviderPrefix

Purpose

Enforces naming conventions for PHPUnit data provider methods. This sniff ensures that data provider methods start with a configurable prefix (default: dataProvider). It provides auto-fixing capabilities to rename methods and update all references.

Configuration

  • prefix: The required prefix for data provider methods (default: dataProvider)

Examples

✓ Valid:

class UserTest extends TestCase {
    /**
     * @dataProvider dataProviderValidCases
     */
    public function testSomething($input, $expected): void {
        $this->assertEquals($expected, $input);
    }

    public function dataProviderValidCases(): array {
        return [['input1', 'expected1']];
    }
}

✗ Invalid:

class UserTest extends TestCase {
    /**
     * @dataProvider providerInvalidCases
     */
    public function testSomething($input, $expected): void {
        $this->assertEquals($expected, $input);
    }

    // ERROR: Data provider method "providerInvalidCases" should start with 
    // prefix "dataProvider", suggested name: "dataProviderInvalidCases"
    public function providerInvalidCases(): array {
        return [['input1', 'expected1']];
    }

    /**
     * @dataProvider casesForAnotherTest
     */
    public function testAnother($value): void {
        $this->assertNotEmpty($value);
    }

    // ERROR: Data provider method "casesForAnotherTest" should start with 
    // prefix "dataProvider", suggested name: "dataProviderForAnotherTest"
    public function casesForAnotherTest(): array {
        return [['value1']];
    }

    /**
     * @dataProvider provideDataForTest
     */
    public function testWithProvide($data): void {
        $this->assertIsString($data);
    }

    // ERROR: Data provider method "provideDataForTest" should start with 
    // prefix "dataProvider", suggested name: "dataProviderDataForTest"
    public function provideDataForTest(): array {
        return [['data1']];
    }
}

DrevOps.TestingPractices.DataProviderMatchesTestName

Purpose

Enforces that data provider method names match the test method names they serve. The provider name must end with the exact test name (after removing the "test" prefix). This improves code readability and maintains a clear relationship between tests and their data providers.

Configuration

None

Examples

✓ Valid:

class UserTest extends TestCase {
    /**
     * @dataProvider dataProviderUserLogin
     */
    public function testUserLogin($user, $pass): void {
        $this->assertNotEmpty($user);
    }

    public function dataProviderUserLogin(): array {
        return [['user1', 'pass1']];
    }

    /**
     * @dataProvider providerEmailValidation
     */
    public function testEmailValidation($email): void {
        $this->assertNotEmpty($email);
    }

    // Different prefix is OK, as long as it ends with "EmailValidation"
    public function providerEmailValidation(): array {
        return [['test@example.com']];
    }

    /**
     * @dataProvider AuthenticationScenarios
     */
    public function testAuthenticationScenarios($scenario): void {
        $this->assertIsString($scenario);
    }

    // No prefix is OK, as long as it matches exactly
    public function AuthenticationScenarios(): array {
        return [['scenario1']];
    }

    #[DataProvider('dataProviderPasswordValidation')]
    public function testPasswordValidation($password): void {
        $this->assertNotEmpty($password);
    }

    // Works with PHP 8 attributes too
    public function dataProviderPasswordValidation(): array {
        return [['password123']];
    }
}

✗ Invalid:

class UserTest extends TestCase {
    /**
     * @dataProvider dataProviderLogin
     */
    public function testUserLogin($user, $pass): void {
        $this->assertNotEmpty($user);
    }

    // ERROR: Data provider method "dataProviderLogin" does not match test 
    // method "testUserLogin". Expected provider name to end with "UserLogin"
    public function dataProviderLogin(): array {
        return [['user1', 'pass1']];
    }

    /**
     * @dataProvider dataProviderEmailValidationCases
     */
    public function testEmailValidation($email): void {
        $this->assertNotEmpty($email);
    }

    // ERROR: Data provider method "dataProviderEmailValidationCases" does not 
    // match test method "testEmailValidation". Expected provider name to end 
    // with "EmailValidation"
    public function dataProviderEmailValidationCases(): array {
        return [['test@example.com']];
    }

    /**
     * @dataProvider providerAuth
     */
    public function testAuthenticationScenarios($scenario): void {
        $this->assertIsString($scenario);
    }

    // ERROR: Data provider method "providerAuth" does not match test method 
    // "testAuthenticationScenarios". Expected provider name to end with 
    // "AuthenticationScenarios"
    public function providerAuth(): array {
        return [['scenario1']];
    }

    #[DataProvider('dataProviderPass')]
    public function testPasswordValidation($password): void {
        $this->assertNotEmpty($password);
    }

    // ERROR: Data provider method "dataProviderPass" does not match test 
    // method "testPasswordValidation". Expected provider name to end with 
    // "PasswordValidation"
    public function dataProviderPass(): array {
        return [['password123']];
    }
}

DrevOps.TestingPractices.DataProviderOrder

Purpose

Enforces ordering of data provider and test methods in test files. This ensures structural organization and improves code readability. By default, data providers should be defined after their test methods. Helper methods between tests and providers are allowed.

Configuration

  • providerPosition: Expected position of data provider relative to test (default: after)
    • after: Data providers should appear after their test methods (default)
    • before: Data providers should appear before their test methods

Examples

✓ Valid (providerPosition="after"):

class UserTest extends TestCase {
    /**
     * @dataProvider dataProviderUserLogin
     */
    public function testUserLogin($user, $pass): void {
        $this->assertNotEmpty($user);
    }

    // Provider after test - CORRECT
    public function dataProviderUserLogin(): array {
        return [['user1', 'pass1']];
    }

    /**
     * @dataProvider dataProviderEmailValidation
     */
    public function testEmailValidation($email): void {
        $this->assertNotEmpty($email);
    }

    // Helper methods between test and provider are allowed
    private function helperValidate(): void {
        // Helper logic
    }

    // Provider still after test - CORRECT
    public function dataProviderEmailValidation(): array {
        return [['test@example.com']];
    }

    #[DataProvider('dataProviderAuthentication')]
    public function testAuthentication($scenario): void {
        $this->assertIsString($scenario);
    }

    // Works with PHP 8 attributes too
    public function dataProviderAuthentication(): array {
        return [['scenario1']];
    }
}

✗ Invalid (providerPosition="after"):

class UserTest extends TestCase {
    // Provider before test - WRONG ORDER
    public function dataProviderUserLogin(): array {
        return [['user1', 'pass1']];
    }

    /**
     * @dataProvider dataProviderUserLogin
     */
    // ERROR: Data provider method "dataProviderUserLogin" (line 10) appears 
    // before test method "testUserLogin" (line 17). Providers should be 
    // defined after their test methods
    public function testUserLogin($user, $pass): void {
        $this->assertNotEmpty($user);
    }

    // Another provider before test - WRONG ORDER
    public function dataProviderEmailValidation(): array {
        return [['test@example.com']];
    }

    /**
     * @dataProvider dataProviderEmailValidation
     */
    // ERROR: Data provider method "dataProviderEmailValidation" (line 24) 
    // appears before test method "testEmailValidation" (line 31). Providers 
    // should be defined after their test methods
    public function testEmailValidation($email): void {
        $this->assertNotEmpty($email);
    }
}

Note: All three rules:

  • Work with both @dataProvider annotations and PHP 8 #[DataProvider] attributes
  • Skip external providers referenced as ClassName::methodName
  • Only apply to test classes (classes ending with Test or TestCase, or extending TestCase)

Full Changelog: 0.4.0...0.5.0

@AlexSkrypnyk

0.4.0 - PHPCS 4 compatibility

20 Nov 08:02

Choose a tag to compare

What's new since 0.3.0

Full Changelog: 0.3.0...0.4.0

@AlexSkrypnyk

0.3.0

18 Nov 01:43

Choose a tag to compare

What's new since 0.2.0

Full Changelog: 0.2.0...0.3.0

@AlexSkrypnyk

0.2.0

01 Nov 11:13

Choose a tag to compare

What's new since 0.1.0

Full Changelog: 0.1.0...0.2.0

@AlexSkrypnyk

0.1.0 - Initial release

01 Nov 10:46

Choose a tag to compare

What's new since

  • Separated rules into LocalVariableSnakeCase and ParameterSnakeCase. @AlexSkrypnyk (#2)
  • Added rule to check for snake case variables. @AlexSkrypnyk (#1)

Full Changelog: ...0.1.0

@AlexSkrypnyk