Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 20 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,26 @@ composer require phauthentic/phpstan-rules --dev

## Rules

See [Rules documentation](docs/Rules.md) for a list of available rules and configuration examples.

- Architecture Rules:
- [Dependency Constraints Rule](docs/Rules.md#dependency-constraints-rule)
- [Forbidden Namespaces Rule](docs/Rules.md#forbidden-namespaces-rule)
- [Readonly Class Rule](docs/Rules.md#readonly-class-rule)
- [Final Class Rule](docs/Rules.md#final-class-rule)
- [Namespace Class Pattern Rule](docs/Rules.md#namespace-class-pattern-rule)
- [Catch Exception of Type Not Allowed Rule](docs/Rules.md#catch-exception-of-type-not-allowed-rule)
- [Methods Returning Bool Must Follow Naming Convention Rule](docs/Rules.md#methods-returning-bool-must-follow-naming-convention-rule)
- [Method Signature Must Match Rule](docs/Rules.md#method-signature-must-match-rule)
- [Method Must Return Type Rule](docs/Rules.md#method-must-return-type-rule)
- Clean Code Rules:
- [Control Structure Nesting Rule](docs/Rules.md#control-structure-nesting-rule)
- [Too Many Arguments Rule](docs/Rules.md#too-many-arguments-rule)
- [Max Line Length Rule](docs/Rules.md#max-line-length-rule)
See individual rule documentation for detailed configuration examples. A [full configuration example](docs/Rules.md) is also available.

### Architecture Rules

- [Dependency Constraints Rule](docs/rules/Dependency-Constraints-Rule.md)
- [Forbidden Namespaces Rule](docs/rules/Forbidden-Namespaces-Rule.md)
- [Class Must Be Readonly Rule](docs/rules/Class-Must-Be-Readonly-Rule.md)
- [Class Must Be Final Rule](docs/rules/Class-Must-Be-Final-Rule.md)
- [Classname Must Match Pattern Rule](docs/rules/Classname-Must-Match-Pattern-Rule.md)
- [Catch Exception Of Type Not Allowed Rule](docs/rules/Catch-Exception-Of-Type-Not-Allowed-Rule.md)
- [Class Must Have Specification Docblock Rule](docs/rules/Class-Must-Have-Specification-Docblock-Rule.md)
- [Methods Returning Bool Must Follow Naming Convention Rule](docs/rules/Methods-Returning-Bool-Must-Follow-Naming-Convention-Rule.md)
- [Method Signature Must Match Rule](docs/rules/Method-Signature-Must-Match-Rule.md)
- [Method Must Return Type Rule](docs/rules/Method-Must-Return-Type-Rule.md)

### Clean Code Rules

- [Control Structure Nesting Rule](docs/rules/Control-Structure-Nesting-Rule.md)
- [Too Many Arguments Rule](docs/rules/Too-Many-Arguments-Rule.md)
- [Max Line Length Rule](docs/rules/Max-Line-Length-Rule.md)

### Using Regex in Rules

Expand Down
21 changes: 21 additions & 0 deletions data/SpecificationDocblock/InvalidMethodDocblockClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace App\SpecificationDocblock;

class InvalidMethodDocblockClass
{
/**
* Specification:
* This is missing the blank line and list items.
*/
public function testMethod(): void
{
}

public function otherMethod(): void
{
}
}

19 changes: 19 additions & 0 deletions data/SpecificationDocblock/InvalidMissingPeriodsClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace App\SpecificationDocblock;

/**
* Specification:
*
* - Removes an item from the recommendation engine
* - Updates the cache accordingly
*/
class InvalidMissingPeriodsClass
{
public function execute(): void
{
}
}

20 changes: 20 additions & 0 deletions data/SpecificationDocblock/InvalidMultiLineNoPeriodClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace App\SpecificationDocblock;

/**
* Specification:
*
* - Removes an item from the recommendation engine
* and updates all related caches
* - Validates the input data
*/
class InvalidMultiLineNoPeriodClass
{
public function execute(): void
{
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace App\SpecificationDocblock;

/**
* Specification:
* - Missing blank line after header.
*/
class InvalidSpecificationNoBlankLineClass
{
public function execute(): void
{
}
}

18 changes: 18 additions & 0 deletions data/SpecificationDocblock/InvalidSpecificationNoListItemClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace App\SpecificationDocblock;

/**
* Specification:
*
* This has no list items.
*/
class InvalidSpecificationNoListItemClass
{
public function execute(): void
{
}
}

13 changes: 13 additions & 0 deletions data/SpecificationDocblock/MissingDocblockClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

declare(strict_types=1);

namespace App\SpecificationDocblock;

class MissingDocblockClass
{
public function execute(): void
{
}
}

17 changes: 17 additions & 0 deletions data/SpecificationDocblock/MissingMethodDocblockClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace App\SpecificationDocblock;

class MissingMethodDocblockClass
{
public function testMethod(): void
{
}

public function otherMethod(): void
{
}
}

18 changes: 18 additions & 0 deletions data/SpecificationDocblock/MissingSpecificationHeaderClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace App\SpecificationDocblock;

/**
* This is just a regular docblock.
*
* - Some item here.
*/
class MissingSpecificationHeaderClass
{
public function execute(): void
{
}
}

116 changes: 116 additions & 0 deletions data/SpecificationDocblock/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Specification Docblock Rule

This directory contains test data for the `ClassMustHaveSpecificationDocblockRule`.

## Rule Configuration Example

```neon
# phpstan.neon
services:
-
class: Phauthentic\PHPStanRules\Architecture\ClassMustHaveSpecificationDocblockRule
arguments:
patterns:
- '/.*Facade$/' # All classes ending with "Facade"
- '/.*Command$/' # All classes ending with "Command"
- '/.*Handler$/' # All classes ending with "Handler"
specificationHeader: 'Specification:' # Optional: customize the header
requireBlankLineAfterHeader: true # Optional: require blank line (default: true)
requireListItemsEndWithPeriod: false # Optional: require periods (default: false)
tags:
- phpstan.rules.rule
```

## Configuration Options

- `patterns`: Array of regex patterns to match class names (required)
- `specificationHeader`: Header text to look for (default: `'Specification:'`)
- `requireBlankLineAfterHeader`: Require blank line after header (default: `true`)
- `requireListItemsEndWithPeriod`: Require list items end with period (default: `false`)

## Valid Specification Format

### Minimum Required Format
```php
/**
* Specification:
*
* - Removes an item from the recommendation engine.
*/
class MyClass {}
```

### Multi-Line List Items
List items can span multiple lines:
```php
/**
* Specification:
*
* - Removes an item from the recommendation engine
* and updates all related caches including user
* preferences and global recommendations.
* - Validates the input data before processing
* and throws an exception if validation fails.
*/
class MyClass {}
```

### With Annotations
```php
/**
* Specification:
*
* - Removes an item from the recommendation engine.
*
* @throws \Exception
*/
class MyClass {}
```

### With Additional Description and Annotations
```php
/**
* Specification:
*
* - Removes an item from the recommendation engine.
* - Updates the cache accordingly.
*
* Some additional description goes here.
*
* @throws \Exception
* @return void
*/
class MyClass {}
```

## Invalid Formats

### Missing Specification Header
```php
/**
* This is just a regular docblock.
*
* - Some item here.
*/
class MyClass {} // ERROR
```

### Missing Blank Line After Header
```php
/**
* Specification:
* - Missing blank line after header.
*/
class MyClass {} // ERROR
```

### Missing List Items
```php
/**
* Specification:
*
* This has no list items.
*/
class MyClass {} // ERROR
```

19 changes: 19 additions & 0 deletions data/SpecificationDocblock/ValidCustomHeaderClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace App\SpecificationDocblock;

/**
* Requirements:
*
* - Removes an item from the recommendation engine.
* - Updates the cache accordingly.
*/
class ValidCustomHeaderClass
{
public function execute(): void
{
}
}

23 changes: 23 additions & 0 deletions data/SpecificationDocblock/ValidMethodDocblockClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace App\SpecificationDocblock;

class ValidMethodDocblockClass
{
/**
* Specification:
*
* - This is a test method with valid specification.
* - It has proper formatting.
*/
public function testMethod(): void
{
}

public function otherMethod(): void
{
}
}

26 changes: 26 additions & 0 deletions data/SpecificationDocblock/ValidMultiLineComplexClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace App\SpecificationDocblock;

/**
* Specification:
*
* - Removes an item from the recommendation engine
* and updates all related caches including:
* - User preferences cache
* - Global recommendations cache
* This ensures consistency across the system.
* - Validates the input data before processing.
*
* @param array $data
* @throws \InvalidArgumentException
*/
class ValidMultiLineComplexClass
{
public function execute(): void
{
}
}

Loading