mirror of
https://github.com/elyby/php-code-style.git
synced 2024-12-22 04:59:57 +05:30
First implementation
This commit is contained in:
parent
c601056af1
commit
0bb3e80827
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/vendor/
|
||||
.php_cs
|
||||
.php_cs.cache
|
9
.php_cs.dist
Normal file
9
.php_cs.dist
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
$finder = PhpCsFixer\Finder::create()
|
||||
->in(__DIR__);
|
||||
|
||||
return \Ely\CS\Config::create([
|
||||
// Disable it for const, 'cause ^7.0 compatibility
|
||||
'visibility_required' => ['property', 'method'],
|
||||
])->setFinder($finder);
|
265
README.md
265
README.md
@ -1,2 +1,263 @@
|
||||
# php-code-style
|
||||
Set of PHP-CS-Fixer rules used in the development of Ely.by PHP projects
|
||||
# Ely.by PHP-CS-Fixer rules
|
||||
|
||||
Set of PHP-CS-Fixer rules used in development of Ely.by PHP projects. It's suited for PHP 7.1 and above.
|
||||
You can use it as a ready-made set of rules or [just some of them](#using-our-fixers).
|
||||
|
||||
## Installation
|
||||
|
||||
First of all install Ely.by PHP-CS-Fixer rules via composer with
|
||||
[PHP-CS-Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer):
|
||||
|
||||
```sh
|
||||
composer require --dev friendsofphp/php-cs-fixer ely/php-code-style
|
||||
```
|
||||
|
||||
Then create file `.php-cs` with following contents:
|
||||
|
||||
```php
|
||||
<?php
|
||||
$finder = \PhpCsFixer\Finder::create()
|
||||
->in(__DIR__);
|
||||
|
||||
return \Ely\CS\Config::create()
|
||||
->setFinder($finder);
|
||||
```
|
||||
|
||||
And that's it. You can now find code style violations with following command:
|
||||
|
||||
```sh
|
||||
vendor/bin/php-cs-fixer --diff --dry-run -v fix
|
||||
```
|
||||
|
||||
And then completely fix them all with:
|
||||
|
||||
```sh
|
||||
vendor/bin/php-cs-fixer fix
|
||||
```
|
||||
|
||||
### Configuration
|
||||
|
||||
You can pass a custom set of rules to the `\Ely\CS\Config::create()` call. For example, it can be used to validate a
|
||||
project with PHP 7.0 compatibility:
|
||||
|
||||
```php
|
||||
<?php
|
||||
return \Ely\CS\Config::create([
|
||||
'visibility_required' => ['property', 'method'],
|
||||
])->setFinder($finder);
|
||||
```
|
||||
|
||||
## Code style
|
||||
|
||||
Our code style is based primarily on [PSR-2](https://www.php-fig.org/psr/psr-2/), while borrowing some ideas from
|
||||
[PSR-12](https://github.com/php-fig/fig-standards/blob/92b198bb/proposed/extended-coding-style-guide.md)
|
||||
with some changes.
|
||||
|
||||
### Example
|
||||
|
||||
This example encompasses some of the rules below as a quick overview:
|
||||
|
||||
```php
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Vendor\Package;
|
||||
|
||||
use Vendor\Package\SomeNamespace\ClassA;
|
||||
|
||||
class Foo extends Bar implements FooInterface {
|
||||
use SomeTrait;
|
||||
|
||||
private const SAMPLE_1 = 123;
|
||||
private const SAMPLE_2 = 321;
|
||||
|
||||
public $field1;
|
||||
|
||||
public $field2;
|
||||
|
||||
public function sampleFunction(int $a, int $b = null): array {
|
||||
if ($a === $b) {
|
||||
$result = bar();
|
||||
} else {
|
||||
$result = BazClass::bar($this->field1, $this->field2);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function setToNull(): self {
|
||||
$this->field1 = null;
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
**Key differences:**
|
||||
|
||||
* Opening braces for classes MUST be **on the same line**.
|
||||
|
||||
* Opening braces for methods MUST be **on the next line**.
|
||||
|
||||
**Additional rules:**
|
||||
|
||||
* There MUST be one empty line before `return` statement, except when there is only one statement before it.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
function a() {
|
||||
$a = '123';
|
||||
return $a . ' is a number';
|
||||
}
|
||||
|
||||
function b() {
|
||||
$a = '123';
|
||||
$b = 'is';
|
||||
|
||||
return $a . ' ' . $b . ' a number';
|
||||
}
|
||||
```
|
||||
|
||||
* There MUST be one blank line around class body, but there MUST be **no blank lines** around anonymous class body.
|
||||
|
||||
```php
|
||||
<?php
|
||||
class Test {
|
||||
|
||||
public function method() {
|
||||
$obj = new class extends Foo {
|
||||
public function overriddenMethod() {
|
||||
// code body
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
* Visibility MUST be declared for all methods, properties and constants.
|
||||
|
||||
* There MUST be one blank line after an each of `if`, `switch`, `for`, `foreach`, `while` and `do-while` bodies.
|
||||
|
||||
```php
|
||||
<?php
|
||||
if (true) {
|
||||
// some actions here
|
||||
}
|
||||
|
||||
echo 'the next statement is here';
|
||||
```
|
||||
|
||||
## Using our fixers
|
||||
|
||||
First of all, you must install Ely.by PHP-CS-Fixer package as described in the [installation chapter](#installation).
|
||||
After that you can enable our custom fixers with `registerCustomFixers` method:
|
||||
|
||||
```php
|
||||
<?php
|
||||
// Your Finder configuration
|
||||
|
||||
return \PhpCsFixer\Config::create()
|
||||
->registerCustomFixers(new \Ely\CS\Fixers());
|
||||
```
|
||||
|
||||
And then you'll be able to use our custom rules.
|
||||
|
||||
### `Ely/blank_line_around_class_body`
|
||||
|
||||
Ensure that a class body contains one blank line after its definition and before its end:
|
||||
|
||||
```diff
|
||||
--- Original
|
||||
+++ New
|
||||
@@ @@
|
||||
<?php
|
||||
class Test {
|
||||
+
|
||||
public function func() {
|
||||
$obj = new class extends Foo {
|
||||
+
|
||||
public $prop;
|
||||
+
|
||||
}
|
||||
}
|
||||
+
|
||||
}
|
||||
```
|
||||
|
||||
**Configuration:**
|
||||
|
||||
* `apply_to_anonymous_classes` - should this fixer be applied to anonymous classes? If it is set to `false`, than
|
||||
anonymous classes will be fixed to don't have empty lines around body. **Default**: `false`.
|
||||
|
||||
* `blank_lines_count` - adjusts an amount of the blank lines. **Default**: `1`.
|
||||
|
||||
### `Ely/blank_line_before_return`
|
||||
|
||||
This is extended version of the original `blank_line_before_statement` fixer. It applies only to `return` statements
|
||||
and only in cases, when on the current nesting level more than one statements.
|
||||
|
||||
```diff
|
||||
--- Original
|
||||
+++ New
|
||||
@@ @@
|
||||
<?php
|
||||
public function foo() {
|
||||
$a = 'this';
|
||||
$b = 'is';
|
||||
+
|
||||
return "$a $b awesome";
|
||||
}
|
||||
|
||||
public function bar() {
|
||||
$this->foo();
|
||||
return 'okay';
|
||||
}
|
||||
```
|
||||
|
||||
### `Ely/line_break_after_statements`
|
||||
|
||||
Ensures that there is one blank line above the next statements: `if`, `switch`, `for`, `foreach`, `while`
|
||||
and `do-while`.
|
||||
|
||||
```diff
|
||||
--- Original
|
||||
+++ New
|
||||
@@ @@
|
||||
<?php
|
||||
$a = 123;
|
||||
if ($a === 123) {
|
||||
// Do something here
|
||||
}
|
||||
+
|
||||
$b = [1, 2, 3];
|
||||
foreach ($b as $number) {
|
||||
if ($number === 3) {
|
||||
echo 'it is three!';
|
||||
}
|
||||
}
|
||||
+
|
||||
$c = 'next statement';
|
||||
```
|
||||
|
||||
### `Ely/new_with_braces`
|
||||
|
||||
This is the extended version of the original `new_with_braces` fixer. It allows you to remove braces around
|
||||
an anonymous class declaration in a case when said class constructor doesn't contain any arguments.
|
||||
|
||||
```diff
|
||||
--- Original
|
||||
+++ New
|
||||
@@ @@
|
||||
<?php
|
||||
-$a = new Foo;
|
||||
+$a = new Foo();
|
||||
-$b = new class() extends Foo {};
|
||||
+$b = new class extends Foo {};
|
||||
```
|
||||
|
||||
**Configuration:**
|
||||
|
||||
* `remove_for_anonymous_classes` - if its set to `true`, then braces for anonymous classes without constructor
|
||||
arguments will be removed. **Default**: `false`.
|
||||
|
38
composer.json
Normal file
38
composer.json
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "ely/php-code-style",
|
||||
"description": "Set of PHP-CS-Fixer rules used in the development of Ely.by PHP projects",
|
||||
"keywords": ["php-cs-fixer", "code style"],
|
||||
"homepage": "https://github.com/elyby/php-code-style",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ely.by team",
|
||||
"email": "team@ely.by"
|
||||
},
|
||||
{
|
||||
"name": "ErickSkrauch",
|
||||
"email": "erickskrauch@ely.by"
|
||||
}
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"type": "library",
|
||||
"require": {
|
||||
"php": "^7.0",
|
||||
"friendsofphp/php-cs-fixer": "^2.11"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Ely\\CS\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Ely\\CS\\Test\\": "tests/"
|
||||
},
|
||||
"files": [
|
||||
"vendor/friendsofphp/php-cs-fixer/tests/Test/Constraint/SameStringsConstraint.php"
|
||||
]
|
||||
}
|
||||
}
|
2406
composer.lock
generated
Normal file
2406
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
39
phpunit.xml.dist
Normal file
39
phpunit.xml.dist
Normal file
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit
|
||||
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
|
||||
backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
beStrictAboutChangesToGlobalState="true"
|
||||
beStrictAboutOutputDuringTests="true"
|
||||
beStrictAboutTestSize="true"
|
||||
beStrictAboutTestsThatDoNotTestAnything="true"
|
||||
beStrictAboutTodoAnnotatedTests="true"
|
||||
bootstrap="./vendor/autoload.php"
|
||||
colors="true"
|
||||
columns="max"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
verbose="true"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite>
|
||||
<directory>./tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>./src</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
|
||||
<php>
|
||||
<ini name="zend.enable_gc" value="0"/>
|
||||
<ini name="memory_limit" value="1G"/>
|
||||
</php>
|
||||
</phpunit>
|
17
src/Config.php
Normal file
17
src/Config.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ely\CS;
|
||||
|
||||
use PhpCsFixer\Config as PhpCsFixerConfig;
|
||||
|
||||
class Config {
|
||||
|
||||
public static function create(array $overwrittenRules = []): PhpCsFixerConfig {
|
||||
return PhpCsFixerConfig::create()
|
||||
->setRiskyAllowed(true)
|
||||
->registerCustomFixers(new Fixers())
|
||||
->setRules(Rules::create($overwrittenRules));
|
||||
}
|
||||
|
||||
}
|
13
src/Fixer/AbstractFixer.php
Normal file
13
src/Fixer/AbstractFixer.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
namespace Ely\CS\Fixer;
|
||||
|
||||
abstract class AbstractFixer extends \PhpCsFixer\AbstractFixer {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName() {
|
||||
return sprintf('Ely/%s', parent::getName());
|
||||
}
|
||||
|
||||
}
|
179
src/Fixer/Operator/NewWithBracesFixer.php
Normal file
179
src/Fixer/Operator/NewWithBracesFixer.php
Normal file
@ -0,0 +1,179 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ely\CS\Fixer\Operator;
|
||||
|
||||
use Ely\CS\Fixer\AbstractFixer;
|
||||
use PhpCsFixer\Fixer\ConfigurationDefinitionFixerInterface;
|
||||
use PhpCsFixer\FixerConfiguration\FixerConfigurationResolver;
|
||||
use PhpCsFixer\FixerConfiguration\FixerOptionBuilder;
|
||||
use PhpCsFixer\FixerDefinition\CodeSample;
|
||||
use PhpCsFixer\FixerDefinition\FixerDefinition;
|
||||
use PhpCsFixer\Tokenizer\CT;
|
||||
use PhpCsFixer\Tokenizer\Token;
|
||||
use PhpCsFixer\Tokenizer\Tokens;
|
||||
|
||||
/**
|
||||
* This is the extended version of the original new_with_braces fixer.
|
||||
* It allows you to remove braces around an anonymous class declaration in a case
|
||||
* when said class constructor doesn't contain any arguments.
|
||||
*
|
||||
* @url https://github.com/FriendsOfPHP/PHP-CS-Fixer/blob/5c5de791ab/src/Fixer/Operator/NewWithBracesFixer.php
|
||||
*
|
||||
* @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
|
||||
*/
|
||||
final class NewWithBracesFixer extends AbstractFixer implements ConfigurationDefinitionFixerInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDefinition() {
|
||||
return new FixerDefinition(
|
||||
'All instances created with new keyword must be followed by braces.',
|
||||
[
|
||||
new CodeSample("<?php \$x = new X;\n"),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCandidate(Tokens $tokens) {
|
||||
return $tokens->isTokenKindFound(T_NEW);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function applyFix(\SplFileInfo $file, Tokens $tokens) {
|
||||
static $nextTokenKinds = null;
|
||||
if ($nextTokenKinds === null) {
|
||||
$nextTokenKinds = [
|
||||
'?',
|
||||
';',
|
||||
',',
|
||||
'(',
|
||||
')',
|
||||
'[',
|
||||
']',
|
||||
':',
|
||||
'<',
|
||||
'>',
|
||||
'+',
|
||||
'-',
|
||||
'*',
|
||||
'/',
|
||||
'%',
|
||||
'&',
|
||||
'^',
|
||||
'|',
|
||||
[T_CLASS],
|
||||
[T_IS_SMALLER_OR_EQUAL],
|
||||
[T_IS_GREATER_OR_EQUAL],
|
||||
[T_IS_EQUAL],
|
||||
[T_IS_NOT_EQUAL],
|
||||
[T_IS_IDENTICAL],
|
||||
[T_IS_NOT_IDENTICAL],
|
||||
[T_CLOSE_TAG],
|
||||
[T_LOGICAL_AND],
|
||||
[T_LOGICAL_OR],
|
||||
[T_LOGICAL_XOR],
|
||||
[T_BOOLEAN_AND],
|
||||
[T_BOOLEAN_OR],
|
||||
[T_SL],
|
||||
[T_SR],
|
||||
[T_INSTANCEOF],
|
||||
[T_AS],
|
||||
[T_DOUBLE_ARROW],
|
||||
[T_POW],
|
||||
[CT::T_ARRAY_SQUARE_BRACE_OPEN],
|
||||
[CT::T_ARRAY_SQUARE_BRACE_CLOSE],
|
||||
[CT::T_BRACE_CLASS_INSTANTIATION_OPEN],
|
||||
[CT::T_BRACE_CLASS_INSTANTIATION_CLOSE],
|
||||
];
|
||||
|
||||
if (defined('T_SPACESHIP')) {
|
||||
$nextTokenKinds[] = [T_SPACESHIP];
|
||||
}
|
||||
}
|
||||
|
||||
for ($index = $tokens->count() - 3; $index > 0; --$index) {
|
||||
$token = $tokens[$index];
|
||||
if (!$token->isGivenKind(T_NEW)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$nextIndex = $tokens->getNextTokenOfKind($index, $nextTokenKinds);
|
||||
$nextToken = $tokens[$nextIndex];
|
||||
|
||||
// new anonymous class definition
|
||||
if ($nextToken->isGivenKind(T_CLASS)) {
|
||||
if ($this->configuration['remove_for_anonymous_classes']) {
|
||||
$nextTokenIndex = $tokens->getNextMeaningfulToken($nextIndex);
|
||||
$nextNextTokenIndex = $tokens->getNextMeaningfulToken($nextTokenIndex);
|
||||
if ($tokens[$nextTokenIndex]->equals('(') && $tokens[$nextNextTokenIndex]->equals(')')) {
|
||||
$this->removeBracesAfter($tokens, $nextIndex);
|
||||
}
|
||||
} else {
|
||||
if (!$tokens[$tokens->getNextMeaningfulToken($nextIndex)]->equals('(')) {
|
||||
$this->insertBracesAfter($tokens, $nextIndex);
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// entrance into array index syntax - need to look for exit
|
||||
while ($nextToken->equals('[')) {
|
||||
$nextIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_INDEX_SQUARE_BRACE, $nextIndex) + 1;
|
||||
$nextToken = $tokens[$nextIndex];
|
||||
}
|
||||
|
||||
// new statement has a gap in it - advance to the next token
|
||||
if ($nextToken->isWhitespace()) {
|
||||
$nextIndex = $tokens->getNextNonWhitespace($nextIndex);
|
||||
$nextToken = $tokens[$nextIndex];
|
||||
}
|
||||
|
||||
// new statement with () - nothing to do
|
||||
if ($nextToken->equals('(')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->insertBracesAfter($tokens, $tokens->getPrevMeaningfulToken($nextIndex));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createConfigurationDefinition() {
|
||||
return new FixerConfigurationResolver([
|
||||
(new FixerOptionBuilder('remove_for_anonymous_classes', 'when enabled will remove braces around an anonymous class declaration in a case when constructor doesn\'t contain any arguments'))
|
||||
->setAllowedTypes(['bool'])
|
||||
->setDefault(false)
|
||||
->getOption(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Tokens $tokens
|
||||
* @param int $index
|
||||
*/
|
||||
private function insertBracesAfter(Tokens $tokens, $index) {
|
||||
$tokens->insertAt(++$index, [new Token('('), new Token(')')]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Tokens $tokens
|
||||
* @param int $index
|
||||
*/
|
||||
private function removeBracesAfter(Tokens $tokens, int $index) {
|
||||
$tokens->clearRange(
|
||||
$tokens->getNextTokenOfKind($index, ['(']),
|
||||
$tokens->getNextTokenOfKind($index, [')'])
|
||||
);
|
||||
}
|
||||
|
||||
}
|
150
src/Fixer/Whitespace/BlankLineAroundClassBodyFixer.php
Normal file
150
src/Fixer/Whitespace/BlankLineAroundClassBodyFixer.php
Normal file
@ -0,0 +1,150 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ely\CS\Fixer\Whitespace;
|
||||
|
||||
use Ely\CS\Fixer\AbstractFixer;
|
||||
use PhpCsFixer\Fixer\ConfigurationDefinitionFixerInterface;
|
||||
use PhpCsFixer\Fixer\WhitespacesAwareFixerInterface;
|
||||
use PhpCsFixer\FixerConfiguration\FixerConfigurationResolver;
|
||||
use PhpCsFixer\FixerConfiguration\FixerOptionBuilder;
|
||||
use PhpCsFixer\FixerDefinition\CodeSample;
|
||||
use PhpCsFixer\FixerDefinition\FixerDefinition;
|
||||
use PhpCsFixer\Tokenizer\Token;
|
||||
use PhpCsFixer\Tokenizer\Tokens;
|
||||
use PhpCsFixer\Tokenizer\TokensAnalyzer;
|
||||
use PhpCsFixer\Utils;
|
||||
|
||||
/**
|
||||
* This is copy of the PR https://github.com/FriendsOfPHP/PHP-CS-Fixer/pull/3688
|
||||
*
|
||||
* @author ErickSkrauch <erickskrauch@ely.by>
|
||||
*/
|
||||
final class BlankLineAroundClassBodyFixer extends AbstractFixer implements ConfigurationDefinitionFixerInterface, WhitespacesAwareFixerInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDefinition() {
|
||||
return new FixerDefinition(
|
||||
'Ensure that class body contains one blank line after class definition and before its end.',
|
||||
[
|
||||
new CodeSample(
|
||||
'<?php
|
||||
class Sample
|
||||
{
|
||||
protected function foo()
|
||||
{
|
||||
}
|
||||
}
|
||||
'
|
||||
),
|
||||
new CodeSample(
|
||||
'<?php
|
||||
new class extends Foo {
|
||||
|
||||
protected function foo()
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
',
|
||||
['apply_to_anonymous_classes' => false]
|
||||
),
|
||||
new CodeSample(
|
||||
'<?php
|
||||
new class extends Foo {
|
||||
protected function foo()
|
||||
{
|
||||
}
|
||||
};
|
||||
',
|
||||
['apply_to_anonymous_classes' => true]
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPriority() {
|
||||
// should be run after the BracesFixer
|
||||
return -26;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCandidate(Tokens $tokens) {
|
||||
return $tokens->isAnyTokenKindsFound(Token::getClassyTokenKinds());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function applyFix(\SplFileInfo $file, Tokens $tokens) {
|
||||
$analyzer = new TokensAnalyzer($tokens);
|
||||
foreach ($tokens as $index => $token) {
|
||||
if (!$token->isClassy()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$countLines = $this->configuration['blank_lines_count'];
|
||||
if (!$this->configuration['apply_to_anonymous_classes'] && $analyzer->isAnonymousClass($index)) {
|
||||
$countLines = 0;
|
||||
}
|
||||
|
||||
$startBraceIndex = $tokens->getNextTokenOfKind($index, ['{']);
|
||||
if ($tokens[$startBraceIndex + 1]->isWhitespace()) {
|
||||
$nextStatementIndex = $tokens->getNextMeaningfulToken($startBraceIndex);
|
||||
// Traits should be placed right after a class opening brace,
|
||||
if ($tokens[$nextStatementIndex]->getContent() !== 'use') {
|
||||
$this->fixBlankLines($tokens, $startBraceIndex + 1, $countLines);
|
||||
}
|
||||
}
|
||||
|
||||
$endBraceIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $startBraceIndex);
|
||||
if ($tokens[$endBraceIndex - 1]->isWhitespace()) {
|
||||
$this->fixBlankLines($tokens, $endBraceIndex - 1, $countLines);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createConfigurationDefinition() {
|
||||
return new FixerConfigurationResolver([
|
||||
(new FixerOptionBuilder('blank_lines_count', 'adjusts an amount of the blank lines.'))
|
||||
->setAllowedTypes(['int'])
|
||||
->setDefault(1)
|
||||
->getOption(),
|
||||
(new FixerOptionBuilder('apply_to_anonymous_classes', 'whether this fixer should be applied to anonymous classes.'))
|
||||
->setAllowedTypes(['bool'])
|
||||
->setDefault(true)
|
||||
->getOption(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup a whitespace token.
|
||||
*
|
||||
* @param Tokens $tokens
|
||||
* @param int $index
|
||||
* @param int $countLines
|
||||
*/
|
||||
private function fixBlankLines(Tokens $tokens, $index, $countLines) {
|
||||
$content = $tokens[$index]->getContent();
|
||||
// Apply fix only in the case when the count lines do not equals to expected
|
||||
if (substr_count($content, "\n") === $countLines + 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The final bit of the whitespace must be the next statement's indentation
|
||||
$lines = Utils::splitLines($content);
|
||||
$eol = $this->whitespacesConfig->getLineEnding();
|
||||
$tokens[$index] = new Token([T_WHITESPACE, str_repeat($eol, $countLines + 1) . end($lines)]);
|
||||
}
|
||||
|
||||
}
|
103
src/Fixer/Whitespace/BlankLineBeforeReturnFixer.php
Normal file
103
src/Fixer/Whitespace/BlankLineBeforeReturnFixer.php
Normal file
@ -0,0 +1,103 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ely\CS\Fixer\Whitespace;
|
||||
|
||||
use Ely\CS\Fixer\AbstractFixer;
|
||||
use PhpCsFixer\Fixer\WhitespacesAwareFixerInterface;
|
||||
use PhpCsFixer\FixerDefinition\CodeSample;
|
||||
use PhpCsFixer\FixerDefinition\FixerDefinition;
|
||||
use PhpCsFixer\Tokenizer\Token;
|
||||
use PhpCsFixer\Tokenizer\Tokens;
|
||||
use SplFileInfo;
|
||||
|
||||
/**
|
||||
* This is extended version of the original `blank_line_before_statement` fixer.
|
||||
* It applies only to `return` statements and only in cases, when on the current nesting level more than one statements.
|
||||
*
|
||||
* @url https://github.com/FriendsOfPHP/PHP-CS-Fixer/blob/5c5de791ab/src/Fixer/Whitespace/BlankLineBeforeStatementFixer.php
|
||||
*
|
||||
* @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
|
||||
* @author Andreas Möller <am@localheinz.com>
|
||||
* @author SpacePossum
|
||||
*/
|
||||
final class BlankLineBeforeReturnFixer extends AbstractFixer implements WhitespacesAwareFixerInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDefinition() {
|
||||
return new FixerDefinition(
|
||||
'An empty line feed should precede a return statement.',
|
||||
[new CodeSample("<?php\nfunction A()\n{\n echo 1;\n return 1;\n}\n")]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function isCandidate(Tokens $tokens) {
|
||||
return $tokens->isTokenKindFound(T_RETURN);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPriority() {
|
||||
// should be run after NoUselessReturnFixer, ClassDefinitionFixer and BracesFixer
|
||||
return -26;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected function applyFix(SplFileInfo $file, Tokens $tokens) {
|
||||
for ($index = 0, $limit = $tokens->count(); $index < $limit; ++$index) {
|
||||
$token = $tokens[$index];
|
||||
if (!$token->isGivenKind(T_RETURN)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$eol = $this->whitespacesConfig->getLineEnding();
|
||||
|
||||
$prevNonWhitespaceToken = $tokens[$tokens->getPrevNonWhitespace($index)];
|
||||
if (!$prevNonWhitespaceToken->equalsAny([';', '}'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$prevIndex = $index - 1;
|
||||
$prevToken = $tokens[$prevIndex];
|
||||
if ($prevToken->isWhitespace()) {
|
||||
$countParts = substr_count($prevToken->getContent(), "\n");
|
||||
if ($countParts === 0) {
|
||||
$tokens[$prevIndex] = new Token([T_WHITESPACE, rtrim($prevToken->getContent(), " \t") . $eol . $eol]);
|
||||
} elseif ($countParts === 1) {
|
||||
$backwardIndex = $prevIndex;
|
||||
do {
|
||||
if (--$backwardIndex < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
$backwardToken = $tokens[$backwardIndex];
|
||||
if ($backwardToken->getContent() === '{') {
|
||||
break;
|
||||
}
|
||||
|
||||
if ($backwardToken->isWhitespace()) {
|
||||
$countParts += substr_count($backwardToken->getContent(), "\n");
|
||||
}
|
||||
} while ($countParts < 3);
|
||||
|
||||
if ($countParts !== 2) {
|
||||
$tokens[$prevIndex] = new Token([T_WHITESPACE, $eol . $prevToken->getContent()]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$tokens->insertAt($index, new Token([T_WHITESPACE, $eol . $eol]));
|
||||
++$index;
|
||||
++$limit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
163
src/Fixer/Whitespace/LineBreakAfterStatementsFixer.php
Normal file
163
src/Fixer/Whitespace/LineBreakAfterStatementsFixer.php
Normal file
@ -0,0 +1,163 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ely\CS\Fixer\Whitespace;
|
||||
|
||||
use Ely\CS\Fixer\AbstractFixer;
|
||||
use PhpCsFixer\Fixer\WhitespacesAwareFixerInterface;
|
||||
use PhpCsFixer\FixerDefinition\CodeSample;
|
||||
use PhpCsFixer\FixerDefinition\FixerDefinition;
|
||||
use PhpCsFixer\Tokenizer\Token;
|
||||
use PhpCsFixer\Tokenizer\Tokens;
|
||||
use PhpCsFixer\Utils;
|
||||
use SplFileInfo;
|
||||
|
||||
/**
|
||||
* This is rewritten version of the original fixer created by @PedroTroller with improved cases validation and
|
||||
* targeted to the PHP-CS-Fixer 2.11 version.
|
||||
*
|
||||
* @url https://github.com/PedroTroller/PhpCSFixer-Custom-Fixers/blob/affdf99f51/src/PedroTroller/CS/Fixer/CodingStyle/LineBreakBetweenStatementsFixer.php
|
||||
*
|
||||
* @author ErickSkrauch <erickskrauch@ely.by>
|
||||
*/
|
||||
final class LineBreakAfterStatementsFixer extends AbstractFixer implements WhitespacesAwareFixerInterface {
|
||||
|
||||
/**
|
||||
* There is no 'do', 'cause the processing of the 'while' also includes do {} while (); construction
|
||||
*/
|
||||
const STATEMENTS = [
|
||||
T_IF,
|
||||
T_SWITCH,
|
||||
T_FOR,
|
||||
T_FOREACH,
|
||||
T_WHILE,
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getDefinition() {
|
||||
return new FixerDefinition(
|
||||
'Ensures that there is one blank line above the control statements',
|
||||
[
|
||||
new CodeSample(
|
||||
'<?php
|
||||
class Foo
|
||||
{
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function foo() {
|
||||
do {
|
||||
// ...
|
||||
} while (true);
|
||||
foreach (["foo", "bar"] as $str) {
|
||||
// ...
|
||||
}
|
||||
if (true === false) {
|
||||
// ...
|
||||
}
|
||||
foreach (["foo", "bar"] as $str) {
|
||||
if ($str === "foo") {
|
||||
// smth
|
||||
}
|
||||
|
||||
}
|
||||
while (true) {
|
||||
// ...
|
||||
}
|
||||
switch("123") {
|
||||
case "123":
|
||||
break;
|
||||
}
|
||||
$a = "next statement";
|
||||
}
|
||||
}
|
||||
'
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function isCandidate(Tokens $tokens) {
|
||||
return $tokens->isAnyTokenKindsFound(self::STATEMENTS);
|
||||
}
|
||||
|
||||
protected function applyFix(SplFileInfo $file, Tokens $tokens) {
|
||||
foreach ($tokens as $index => $token) {
|
||||
if (!$token->isGivenKind(self::STATEMENTS)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$endStatementIndex = $this->findStatementEnd($tokens, $index);
|
||||
$nextStatementIndex = $tokens->getNextNonWhitespace($endStatementIndex);
|
||||
if ($nextStatementIndex === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($tokens[$nextStatementIndex]->equals('}')) {
|
||||
$this->fixBlankLines($tokens, $endStatementIndex + 1, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->fixBlankLines($tokens, $endStatementIndex + 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
private function fixBlankLines(Tokens $tokens, $index, $countLines) {
|
||||
$content = $tokens[$index]->getContent();
|
||||
// Apply fix only in the case when the count lines do not equals to expected
|
||||
if (substr_count($content, "\n") === $countLines + 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The final bit of the whitespace must be the next statement's indentation
|
||||
$lines = Utils::splitLines($content);
|
||||
$eol = $this->whitespacesConfig->getLineEnding();
|
||||
$tokens[$index] = new Token([T_WHITESPACE, str_repeat($eol, $countLines + 1) . end($lines)]);
|
||||
}
|
||||
|
||||
private function findStatementEnd(Tokens $tokens, int $index): int {
|
||||
$nextIndex = $tokens->getNextMeaningfulToken($index);
|
||||
$nextToken = $tokens[$nextIndex];
|
||||
|
||||
if ($nextToken->equals('(')) {
|
||||
$parenthesisEndIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $nextIndex);
|
||||
$possibleStartBraceIndex = $tokens->getNextNonWhitespace($parenthesisEndIndex);
|
||||
} else {
|
||||
$possibleStartBraceIndex = $nextIndex;
|
||||
}
|
||||
|
||||
// `do {} while ();`
|
||||
if ($tokens[$index]->isGivenKind(T_WHILE) && $tokens[$possibleStartBraceIndex]->equals(';')) {
|
||||
return $possibleStartBraceIndex;
|
||||
}
|
||||
|
||||
$blockEnd = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $possibleStartBraceIndex);
|
||||
$nextStatementIndex = $tokens->getNextMeaningfulToken($blockEnd);
|
||||
if ($nextStatementIndex === null) {
|
||||
return $blockEnd;
|
||||
}
|
||||
|
||||
// `if () {} elseif {}`
|
||||
if ($tokens[$nextStatementIndex]->isGivenKind(T_ELSEIF)) {
|
||||
return $this->findStatementEnd($tokens, $nextStatementIndex);
|
||||
}
|
||||
|
||||
// `if () {} else if {}` or simple `if () {} else {}`
|
||||
if ($tokens[$nextStatementIndex]->isGivenKind(T_ELSE)) {
|
||||
$nextNextStatementIndex = $tokens->getNextMeaningfulToken($nextStatementIndex);
|
||||
if ($tokens[$nextNextStatementIndex]->isGivenKind(T_IF)) {
|
||||
return $this->findStatementEnd($tokens, $nextNextStatementIndex);
|
||||
}
|
||||
|
||||
return $this->findStatementEnd($tokens, $nextStatementIndex);
|
||||
}
|
||||
|
||||
return $blockEnd;
|
||||
}
|
||||
|
||||
}
|
39
src/Fixers.php
Normal file
39
src/Fixers.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ely\CS;
|
||||
|
||||
use ArrayIterator;
|
||||
use IteratorAggregate;
|
||||
use PhpCsFixer\Finder;
|
||||
use PhpCsFixer\Fixer\FixerInterface;
|
||||
use ReflectionClass;
|
||||
use Traversable;
|
||||
|
||||
class Fixers implements IteratorAggregate {
|
||||
|
||||
public function getIterator(): Traversable {
|
||||
$finder = new Finder();
|
||||
$finder->in(__DIR__ . '/Fixer')->name('*.php');
|
||||
$classes = [];
|
||||
foreach ($finder as $file) {
|
||||
$class = '\\Ely\\CS' . str_replace('/', '\\', mb_substr($file->getPathname(), mb_strlen(__DIR__), -4));
|
||||
if (!class_exists($class)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/** @noinspection PhpUnhandledExceptionInspection */
|
||||
$rfl = new ReflectionClass($class);
|
||||
if (!$rfl->implementsInterface(FixerInterface::class) || $rfl->isAbstract()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$classes[] = $class;
|
||||
}
|
||||
|
||||
return new ArrayIterator(array_map(function($class) {
|
||||
return new $class();
|
||||
}, $classes));
|
||||
}
|
||||
|
||||
}
|
74
src/Rules.php
Normal file
74
src/Rules.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ely\CS;
|
||||
|
||||
class Rules {
|
||||
|
||||
private static $rules = [
|
||||
'@PSR2' => true,
|
||||
'binary_operator_spaces' => true,
|
||||
'braces' => [
|
||||
'position_after_functions_and_oop_constructs' => 'same',
|
||||
],
|
||||
'cast_spaces' => [
|
||||
'space' => 'none',
|
||||
],
|
||||
'class_attributes_separation' => [
|
||||
'elements' => ['method', 'property'],
|
||||
],
|
||||
'compact_nullable_typehint' => true,
|
||||
'concat_space' => [
|
||||
'spacing' => 'one',
|
||||
],
|
||||
'declare_equal_normalize' => true,
|
||||
'function_declaration' => [
|
||||
'closure_function_spacing' => 'none',
|
||||
],
|
||||
'function_to_constant' => true,
|
||||
'include' => true,
|
||||
'linebreak_after_opening_tag' => true,
|
||||
'method_chaining_indentation' => true,
|
||||
'modernize_types_casting' => true,
|
||||
'no_short_bool_cast' => true,
|
||||
'no_trailing_comma_in_singleline_array' => true,
|
||||
'no_unneeded_final_method' => true,
|
||||
'no_unused_imports' => true,
|
||||
'no_useless_else' => true,
|
||||
'no_whitespace_before_comma_in_array' => true,
|
||||
'no_whitespace_in_blank_line' => true,
|
||||
'non_printable_character' => [
|
||||
'use_escape_sequences_in_strings' => true,
|
||||
],
|
||||
'object_operator_without_whitespace' => true,
|
||||
'ordered_class_elements' => true,
|
||||
'ordered_imports' => true,
|
||||
'random_api_migration' => true,
|
||||
'return_type_declaration' => [
|
||||
'space_before' => 'none',
|
||||
],
|
||||
'single_quote' => true,
|
||||
'strict_comparison' => true,
|
||||
'ternary_operator_spaces' => true,
|
||||
'ternary_to_null_coalescing' => true,
|
||||
'trailing_comma_in_multiline_array' => true,
|
||||
'visibility_required' => [
|
||||
'elements' => ['property', 'method', 'const'],
|
||||
],
|
||||
'whitespace_after_comma_in_array' => true,
|
||||
// Our custom or extended fixers
|
||||
'Ely/blank_line_around_class_body' => [
|
||||
'apply_to_anonymous_classes' => false,
|
||||
],
|
||||
'Ely/blank_line_before_return' => true,
|
||||
'Ely/line_break_after_statements' => true,
|
||||
'Ely/new_with_braces' => [
|
||||
'remove_for_anonymous_classes' => true,
|
||||
],
|
||||
];
|
||||
|
||||
public static function create(array $overwrittenRules = []): array {
|
||||
return array_merge(self::$rules, $overwrittenRules);
|
||||
}
|
||||
|
||||
}
|
319
tests/Fixer/Operator/NewWithBracesFixerTest.php
Normal file
319
tests/Fixer/Operator/NewWithBracesFixerTest.php
Normal file
@ -0,0 +1,319 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ely\CS\Test\Fixer\Operator;
|
||||
|
||||
use Ely\CS\Fixer\Operator\NewWithBracesFixer;
|
||||
use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
|
||||
|
||||
/**
|
||||
* Original file copied from:
|
||||
* @url https://github.com/FriendsOfPHP/PHP-CS-Fixer/blob/5c5de791ab/tests/Fixer/Operator/NewWithBracesFixerTest.php
|
||||
*
|
||||
* @covers \Ely\CS\Fixer\Operator\NewWithBracesFixer
|
||||
*/
|
||||
class NewWithBracesFixerTest extends AbstractFixerTestCase {
|
||||
|
||||
private static $removeForAnonymousClasses = ['remove_for_anonymous_classes' => true];
|
||||
|
||||
/**
|
||||
* @param string $expected
|
||||
* @param null|string $input
|
||||
*
|
||||
* @dataProvider provideFixCases
|
||||
*/
|
||||
public function testFix($expected, $input = null) {
|
||||
$this->doTest($expected, $input);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $expected
|
||||
* @param null|string $input
|
||||
*
|
||||
* @dataProvider provideFix70Cases
|
||||
* @requires PHP 7.0
|
||||
*/
|
||||
public function testFix70($expected, $input = null, array $configuration = null) {
|
||||
if ($configuration !== null) {
|
||||
$this->fixer->configure($configuration);
|
||||
}
|
||||
|
||||
$this->doTest($expected, $input);
|
||||
}
|
||||
|
||||
public function provideFixCases() {
|
||||
return [
|
||||
[
|
||||
'<?php class A { public function B(){ $static = new static(new \SplFileInfo(__FILE__)); }}',
|
||||
],
|
||||
[
|
||||
'<?php $static = new self(new \SplFileInfo(__FILE__));',
|
||||
],
|
||||
[
|
||||
'<?php $x = new X/**/ /**/ /**//**//**/ /**//**/ (/**/ /**/ /**//**//**/ /**//**/)/**/ /**/ /**//**//**/ /**//**/;/**/ /**/ /**//**//**/ /**//**/',
|
||||
],
|
||||
[
|
||||
'<?php $x = new X();',
|
||||
'<?php $x = new X;',
|
||||
],
|
||||
[
|
||||
'<?php $y = new Y() ;',
|
||||
'<?php $y = new Y ;',
|
||||
],
|
||||
[
|
||||
'<?php $x = new Z() /**/;//',
|
||||
'<?php $x = new Z /**/;//',
|
||||
],
|
||||
[
|
||||
'<?php $foo = new $foo();',
|
||||
'<?php $foo = new $foo;',
|
||||
],
|
||||
[
|
||||
'<?php $xyz = new X(new Y(new Z()));',
|
||||
'<?php $xyz = new X(new Y(new Z));',
|
||||
],
|
||||
[
|
||||
'<?php $foo = (new $bar())->foo;',
|
||||
'<?php $foo = (new $bar)->foo;',
|
||||
],
|
||||
[
|
||||
'<?php $foo = (new $bar((new Foo())->bar))->foo;',
|
||||
'<?php $foo = (new $bar((new Foo)->bar))->foo;',
|
||||
],
|
||||
[
|
||||
'<?php $self = new self();',
|
||||
'<?php $self = new self;',
|
||||
],
|
||||
[
|
||||
'<?php $static = new static();',
|
||||
'<?php $static = new static;',
|
||||
],
|
||||
[
|
||||
'<?php $a = array( "key" => new DateTime(), );',
|
||||
'<?php $a = array( "key" => new DateTime, );',
|
||||
],
|
||||
[
|
||||
'<?php $a = array( "key" => new DateTime() );',
|
||||
'<?php $a = array( "key" => new DateTime );',
|
||||
],
|
||||
[
|
||||
'<?php $a = new $b[$c]();',
|
||||
'<?php $a = new $b[$c];',
|
||||
],
|
||||
[
|
||||
'<?php $a = new $b[$c[$d ? foo() : bar("bar[...]") - 1]]();',
|
||||
'<?php $a = new $b[$c[$d ? foo() : bar("bar[...]") - 1]];',
|
||||
],
|
||||
[
|
||||
'<?php $a = new $b[\'class\']();',
|
||||
'<?php $a = new $b[\'class\'];',
|
||||
],
|
||||
[
|
||||
'<?php $a = new $b[\'class\'] ($foo[\'bar\']);',
|
||||
],
|
||||
[
|
||||
'<?php $a = new $b[\'class\'] () ;',
|
||||
],
|
||||
[
|
||||
'<?php $a = new $b[$c] ($hello[$world]) ;',
|
||||
],
|
||||
[
|
||||
"<?php \$a = new \$b['class']()\r\n\t ;",
|
||||
"<?php \$a = new \$b['class']\r\n\t ;",
|
||||
],
|
||||
[
|
||||
'<?php $a = $b ? new DateTime() : $b;',
|
||||
'<?php $a = $b ? new DateTime : $b;',
|
||||
],
|
||||
[
|
||||
'<?php new self::$adapters[$name]["adapter"]();',
|
||||
'<?php new self::$adapters[$name]["adapter"];',
|
||||
],
|
||||
[
|
||||
'<?php $a = new \Exception()?> <?php echo 1;',
|
||||
'<?php $a = new \Exception?> <?php echo 1;',
|
||||
],
|
||||
[
|
||||
'<?php $b = new \StdClass() /**/?>',
|
||||
'<?php $b = new \StdClass /**/?>',
|
||||
],
|
||||
[
|
||||
'<?php $a = new Foo() instanceof Foo;',
|
||||
'<?php $a = new Foo instanceof Foo;',
|
||||
],
|
||||
[
|
||||
'<?php
|
||||
$a = new Foo() + 1;
|
||||
$a = new Foo() - 1;
|
||||
$a = new Foo() * 1;
|
||||
$a = new Foo() / 1;
|
||||
$a = new Foo() % 1;
|
||||
',
|
||||
'<?php
|
||||
$a = new Foo + 1;
|
||||
$a = new Foo - 1;
|
||||
$a = new Foo * 1;
|
||||
$a = new Foo / 1;
|
||||
$a = new Foo % 1;
|
||||
',
|
||||
],
|
||||
[
|
||||
'<?php
|
||||
$a = new Foo() & 1;
|
||||
$a = new Foo() | 1;
|
||||
$a = new Foo() ^ 1;
|
||||
$a = new Foo() << 1;
|
||||
$a = new Foo() >> 1;
|
||||
',
|
||||
'<?php
|
||||
$a = new Foo & 1;
|
||||
$a = new Foo | 1;
|
||||
$a = new Foo ^ 1;
|
||||
$a = new Foo << 1;
|
||||
$a = new Foo >> 1;
|
||||
',
|
||||
],
|
||||
[
|
||||
'<?php
|
||||
$a = new Foo() and 1;
|
||||
$a = new Foo() or 1;
|
||||
$a = new Foo() xor 1;
|
||||
$a = new Foo() && 1;
|
||||
$a = new Foo() || 1;
|
||||
',
|
||||
'<?php
|
||||
$a = new Foo and 1;
|
||||
$a = new Foo or 1;
|
||||
$a = new Foo xor 1;
|
||||
$a = new Foo && 1;
|
||||
$a = new Foo || 1;
|
||||
',
|
||||
],
|
||||
[
|
||||
'<?php
|
||||
if (new DateTime() > $this->startDate) {}
|
||||
if (new DateTime() >= $this->startDate) {}
|
||||
if (new DateTime() < $this->startDate) {}
|
||||
if (new DateTime() <= $this->startDate) {}
|
||||
if (new DateTime() == $this->startDate) {}
|
||||
if (new DateTime() != $this->startDate) {}
|
||||
if (new DateTime() <> $this->startDate) {}
|
||||
if (new DateTime() === $this->startDate) {}
|
||||
if (new DateTime() !== $this->startDate) {}
|
||||
',
|
||||
'<?php
|
||||
if (new DateTime > $this->startDate) {}
|
||||
if (new DateTime >= $this->startDate) {}
|
||||
if (new DateTime < $this->startDate) {}
|
||||
if (new DateTime <= $this->startDate) {}
|
||||
if (new DateTime == $this->startDate) {}
|
||||
if (new DateTime != $this->startDate) {}
|
||||
if (new DateTime <> $this->startDate) {}
|
||||
if (new DateTime === $this->startDate) {}
|
||||
if (new DateTime !== $this->startDate) {}
|
||||
',
|
||||
],
|
||||
[
|
||||
'<?php $a = new \stdClass() ? $b : $c;',
|
||||
'<?php $a = new \stdClass ? $b : $c;',
|
||||
],
|
||||
[
|
||||
'<?php foreach (new Collection() as $x) {}',
|
||||
'<?php foreach (new Collection as $x) {}',
|
||||
],
|
||||
[
|
||||
'<?php $a = [(string) new Foo() => 1];',
|
||||
'<?php $a = [(string) new Foo => 1];',
|
||||
],
|
||||
[
|
||||
'<?php $a = [ "key" => new DateTime(), ];',
|
||||
'<?php $a = [ "key" => new DateTime, ];',
|
||||
],
|
||||
[
|
||||
'<?php $a = [ "key" => new DateTime() ];',
|
||||
'<?php $a = [ "key" => new DateTime ];',
|
||||
],
|
||||
[
|
||||
'<?php
|
||||
$a = new Foo() ** 1;
|
||||
',
|
||||
'<?php
|
||||
$a = new Foo ** 1;
|
||||
',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function provideFix70Cases() {
|
||||
return [
|
||||
[
|
||||
'<?php
|
||||
$a = new Foo() <=> 1;
|
||||
',
|
||||
'<?php
|
||||
$a = new Foo <=> 1;
|
||||
',
|
||||
],
|
||||
[
|
||||
'<?php
|
||||
$a = new class() {use SomeTrait;};
|
||||
$a = new class() implements Foo{};
|
||||
$a = new class() /**/ extends Bar1{};
|
||||
$a = new class() extends Bar2 implements Foo{};
|
||||
$a = new class() extends Bar3 implements Foo, Foo2{};
|
||||
$a = new class() {}?>
|
||||
',
|
||||
'<?php
|
||||
$a = new class {use SomeTrait;};
|
||||
$a = new class implements Foo{};
|
||||
$a = new class /**/ extends Bar1{};
|
||||
$a = new class extends Bar2 implements Foo{};
|
||||
$a = new class extends Bar3 implements Foo, Foo2{};
|
||||
$a = new class {}?>
|
||||
',
|
||||
],
|
||||
[
|
||||
'<?php
|
||||
class A {
|
||||
public function B() {
|
||||
$static = new static(new class(){});
|
||||
}
|
||||
}
|
||||
',
|
||||
'<?php
|
||||
class A {
|
||||
public function B() {
|
||||
$static = new static(new class{});
|
||||
}
|
||||
}
|
||||
',
|
||||
],
|
||||
[
|
||||
'<?php
|
||||
$a = new class {use SomeTrait;};
|
||||
$a = new class implements Foo{};
|
||||
$a = new class /**/ extends Bar1{};
|
||||
$a = new class extends Bar2 implements Foo{};
|
||||
$a = new class extends Bar3 implements Foo, Foo2{};
|
||||
$a = new class {};
|
||||
$a = new class {};
|
||||
',
|
||||
'<?php
|
||||
$a = new class() {use SomeTrait;};
|
||||
$a = new class() implements Foo{};
|
||||
$a = new class() /**/ extends Bar1{};
|
||||
$a = new class() extends Bar2 implements Foo{};
|
||||
$a = new class() extends Bar3 implements Foo, Foo2{};
|
||||
$a = new class() {};
|
||||
$a = new class( ) {};
|
||||
',
|
||||
self::$removeForAnonymousClasses,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
protected function createFixer() {
|
||||
return new NewWithBracesFixer();
|
||||
}
|
||||
|
||||
}
|
364
tests/Fixer/Whitespace/BlankLineAroundClassBodyFixerTest.php
Normal file
364
tests/Fixer/Whitespace/BlankLineAroundClassBodyFixerTest.php
Normal file
@ -0,0 +1,364 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ely\CS\Test\Fixer\Whitespace;
|
||||
|
||||
use Ely\CS\Fixer\Whitespace\BlankLineAroundClassBodyFixer;
|
||||
use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
|
||||
use PhpCsFixer\WhitespacesFixerConfig;
|
||||
|
||||
/**
|
||||
* @author ErickSkrauch <erickskrauch@ely.by>
|
||||
*
|
||||
* @covers \Ely\CS\Fixer\Whitespace\BlankLineAroundClassBodyFixer
|
||||
*/
|
||||
final class BlankLineAroundClassBodyFixerTest extends AbstractFixerTestCase {
|
||||
|
||||
private static $configurationDoNotApplyForAnonymousClasses = ['apply_to_anonymous_classes' => false];
|
||||
|
||||
private static $configurationTwoEmptyLines = ['blank_lines_count' => 2];
|
||||
|
||||
/**
|
||||
* @param string $expected
|
||||
* @param null|string $input
|
||||
* @param null|array $configuration
|
||||
*
|
||||
* @dataProvider provideFixCases
|
||||
*/
|
||||
public function testFix($expected, $input = null, array $configuration = null) {
|
||||
if (null !== $configuration) {
|
||||
$this->fixer->configure($configuration);
|
||||
}
|
||||
|
||||
$this->doTest($expected, $input);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $expected
|
||||
* @param null|string $input
|
||||
* @param array $configuration
|
||||
*
|
||||
* @dataProvider provideAnonymousClassesCases
|
||||
* @requires PHP 7.0
|
||||
*/
|
||||
public function testFixAnonymousClasses($expected, $input = null, array $configuration = null) {
|
||||
if (null !== $configuration) {
|
||||
$this->fixer->configure($configuration);
|
||||
}
|
||||
|
||||
$this->doTest($expected, $input);
|
||||
}
|
||||
|
||||
public function provideFixCases() {
|
||||
$cases = [];
|
||||
|
||||
$cases[] = [
|
||||
'<?php
|
||||
class Good
|
||||
{
|
||||
|
||||
public function firstMethod()
|
||||
{
|
||||
//code here
|
||||
}
|
||||
|
||||
}',
|
||||
'<?php
|
||||
class Good
|
||||
{
|
||||
public function firstMethod()
|
||||
{
|
||||
//code here
|
||||
}
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
class Good
|
||||
{
|
||||
|
||||
/**
|
||||
* Also blank line before DocBlock
|
||||
*/
|
||||
public function firstMethod()
|
||||
{
|
||||
//code here
|
||||
}
|
||||
|
||||
}',
|
||||
'<?php
|
||||
class Good
|
||||
{
|
||||
/**
|
||||
* Also blank line before DocBlock
|
||||
*/
|
||||
public function firstMethod()
|
||||
{
|
||||
//code here
|
||||
}
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
class Good
|
||||
{
|
||||
|
||||
/**
|
||||
* Too many whitespaces
|
||||
*/
|
||||
public function firstMethod()
|
||||
{
|
||||
//code here
|
||||
}
|
||||
|
||||
}',
|
||||
'<?php
|
||||
class Good
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Too many whitespaces
|
||||
*/
|
||||
public function firstMethod()
|
||||
{
|
||||
//code here
|
||||
}
|
||||
|
||||
|
||||
|
||||
}',
|
||||
];
|
||||
|
||||
$cases[] = [
|
||||
'<?php
|
||||
interface Good
|
||||
{
|
||||
|
||||
/**
|
||||
* Also blank line before DocBlock
|
||||
*/
|
||||
public function firstMethod();
|
||||
|
||||
}',
|
||||
'<?php
|
||||
interface Good
|
||||
{
|
||||
/**
|
||||
* Also blank line before DocBlock
|
||||
*/
|
||||
public function firstMethod();
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
trait Good
|
||||
{
|
||||
|
||||
/**
|
||||
* Also no blank line before DocBlock
|
||||
*/
|
||||
public function firstMethod() {}
|
||||
|
||||
}',
|
||||
'<?php
|
||||
trait Good
|
||||
{
|
||||
/**
|
||||
* Also no blank line before DocBlock
|
||||
*/
|
||||
public function firstMethod() {}
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
class Good
|
||||
{
|
||||
use Foo\bar;
|
||||
|
||||
public function firstMethod()
|
||||
{
|
||||
//code here
|
||||
}
|
||||
|
||||
}',
|
||||
'<?php
|
||||
class Good
|
||||
{
|
||||
use Foo\bar;
|
||||
|
||||
public function firstMethod()
|
||||
{
|
||||
//code here
|
||||
}
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
class Good
|
||||
{
|
||||
use Foo\bar;
|
||||
use Foo\baz;
|
||||
|
||||
public function firstMethod()
|
||||
{
|
||||
//code here
|
||||
}
|
||||
|
||||
}',
|
||||
'<?php
|
||||
class Good
|
||||
{
|
||||
use Foo\bar;
|
||||
use Foo\baz;
|
||||
|
||||
public function firstMethod()
|
||||
{
|
||||
//code here
|
||||
}
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
class Good
|
||||
{
|
||||
use Foo, Bar {
|
||||
Bar::smallTalk insteadof A;
|
||||
Foo::bigTalk insteadof B;
|
||||
}
|
||||
|
||||
public function firstMethod()
|
||||
{
|
||||
//code here
|
||||
}
|
||||
|
||||
}',
|
||||
'<?php
|
||||
class Good
|
||||
{
|
||||
use Foo, Bar {
|
||||
Bar::smallTalk insteadof A;
|
||||
Foo::bigTalk insteadof B;
|
||||
}
|
||||
|
||||
public function firstMethod()
|
||||
{
|
||||
//code here
|
||||
}
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
class Good
|
||||
{
|
||||
|
||||
|
||||
public function firstMethod()
|
||||
{
|
||||
//code here
|
||||
}
|
||||
|
||||
|
||||
}',
|
||||
'<?php
|
||||
class Good
|
||||
{
|
||||
public function firstMethod()
|
||||
{
|
||||
//code here
|
||||
}
|
||||
}',
|
||||
self::$configurationTwoEmptyLines,
|
||||
];
|
||||
|
||||
// check if some fancy whitespaces aren't modified
|
||||
$cases[] = [
|
||||
'<?php
|
||||
class Good
|
||||
{public
|
||||
|
||||
|
||||
|
||||
function firstMethod()
|
||||
{
|
||||
//code here
|
||||
}
|
||||
|
||||
}',
|
||||
];
|
||||
|
||||
return $cases;
|
||||
}
|
||||
|
||||
public function provideAnonymousClassesCases() {
|
||||
$cases = [];
|
||||
|
||||
$cases[] = [
|
||||
'<?php
|
||||
$class = new class extends \Foo {
|
||||
|
||||
public $field;
|
||||
|
||||
public function firstMethod() {}
|
||||
|
||||
};',
|
||||
'<?php
|
||||
$class = new class extends \Foo {
|
||||
public $field;
|
||||
|
||||
public function firstMethod() {}
|
||||
};',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
$class = new class extends \Foo {
|
||||
public $field;
|
||||
|
||||
public function firstMethod() {}
|
||||
};',
|
||||
'<?php
|
||||
$class = new class extends \Foo {
|
||||
|
||||
public $field;
|
||||
|
||||
public function firstMethod() {}
|
||||
|
||||
};',
|
||||
self::$configurationDoNotApplyForAnonymousClasses,
|
||||
];
|
||||
|
||||
return $cases;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $expected
|
||||
* @param null|string $input
|
||||
*
|
||||
* @dataProvider provideMessyWhitespacesCases
|
||||
*/
|
||||
public function testMessyWhitespaces($expected, $input = null) {
|
||||
/** @var \PhpCsFixer\Fixer\WhitespacesAwareFixerInterface $fixer */
|
||||
$fixer = $this->fixer;
|
||||
$fixer->setWhitespacesConfig(new WhitespacesFixerConfig("\t", "\r\n"));
|
||||
|
||||
$this->doTest($expected, $input);
|
||||
}
|
||||
|
||||
public function provideMessyWhitespacesCases() {
|
||||
return [
|
||||
[
|
||||
"<?php\nclass Foo\n{\r\n\r\n public function bar() {}\r\n\r\n}",
|
||||
"<?php\nclass Foo\n{\n public function bar() {}\n}",
|
||||
],
|
||||
[
|
||||
"<?php\nclass Foo\n{\r\n\r\n public function bar() {}\r\n\r\n}",
|
||||
"<?php\nclass Foo\n{\r\n\r\n\n\n public function bar() {}\n\n\n\n}",
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
protected function createFixer() {
|
||||
return new BlankLineAroundClassBodyFixer();
|
||||
}
|
||||
|
||||
}
|
223
tests/Fixer/Whitespace/BlankLineBeforeReturnFixerTest.php
Normal file
223
tests/Fixer/Whitespace/BlankLineBeforeReturnFixerTest.php
Normal file
@ -0,0 +1,223 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ely\CS\Test\Fixer\Whitespace;
|
||||
|
||||
use Ely\CS\Fixer\Whitespace\BlankLineBeforeReturnFixer;
|
||||
use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
|
||||
use PhpCsFixer\WhitespacesFixerConfig;
|
||||
|
||||
/**
|
||||
* Original file copied from:
|
||||
* @url https://github.com/FriendsOfPHP/PHP-CS-Fixer/blob/5c5de791ab/tests/Fixer/Whitespace/BlankLineBeforeStatementFixerTest.php
|
||||
*
|
||||
* @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
|
||||
* @author Andreas Möller <am@localheinz.com>
|
||||
* @author SpacePossum
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @property BlankLineBeforeReturnFixer $fixer
|
||||
*
|
||||
* @covers \Ely\CS\Fixer\Whitespace\BlankLineBeforeReturnFixer
|
||||
*/
|
||||
final class BlankLineBeforeReturnFixerTest extends AbstractFixerTestCase {
|
||||
|
||||
/**
|
||||
* @param string $expected
|
||||
* @param null|string $input
|
||||
*
|
||||
* @dataProvider provideFixCases
|
||||
*/
|
||||
public function testFix($expected, $input = null) {
|
||||
$this->doTest($expected, $input);
|
||||
}
|
||||
|
||||
public function provideFixCases() {
|
||||
$cases = [];
|
||||
$cases[] = [
|
||||
'$a = $a;
|
||||
return $a;
|
||||
',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
$a = $a;
|
||||
|
||||
return $a;',
|
||||
'<?php
|
||||
$a = $a; return $a;',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
$b = $b;
|
||||
|
||||
return $b;',
|
||||
'<?php
|
||||
$b = $b;return $b;',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
$c = $c;
|
||||
|
||||
return $c;',
|
||||
'<?php
|
||||
$c = $c;
|
||||
return $c;',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
$d = $d;
|
||||
|
||||
return $d;',
|
||||
'<?php
|
||||
$d = $d;
|
||||
return $d;',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
if (true) {
|
||||
return 1;
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
if (true)
|
||||
return 1;
|
||||
',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
if (true) {
|
||||
return 1;
|
||||
} else {
|
||||
return 2;
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
if (true)
|
||||
return 1;
|
||||
else
|
||||
return 2;
|
||||
',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
if (true) {
|
||||
return 1;
|
||||
} elseif (false) {
|
||||
return 2;
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
if (true)
|
||||
return 1;
|
||||
elseif (false)
|
||||
return 2;
|
||||
',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
throw new Exception("return true;");',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
function foo()
|
||||
{
|
||||
// comment
|
||||
return "foo";
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
function foo()
|
||||
{
|
||||
// comment
|
||||
|
||||
return "bar";
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
function foo()
|
||||
{
|
||||
// comment
|
||||
return "bar";
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
function foo() {
|
||||
$a = "a";
|
||||
$b = "b";
|
||||
|
||||
return $a . $b;
|
||||
}',
|
||||
'<?php
|
||||
function foo() {
|
||||
$a = "a";
|
||||
$b = "b";
|
||||
return $a . $b;
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
function foo() {
|
||||
$b = "b";
|
||||
return $a . $b;
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
function foo() {
|
||||
$a = "a";
|
||||
|
||||
return $a . "hello";
|
||||
}
|
||||
|
||||
function bar() {
|
||||
$b = "b";
|
||||
return $b . "hello";
|
||||
}
|
||||
',
|
||||
];
|
||||
|
||||
return $cases;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $expected
|
||||
* @param null|string $input
|
||||
*
|
||||
* @dataProvider provideMessyWhitespacesCases
|
||||
*/
|
||||
public function testMessyWhitespaces($expected, $input = null) {
|
||||
$this->fixer->setWhitespacesConfig(new WhitespacesFixerConfig("\t", "\r\n"));
|
||||
|
||||
$this->doTest($expected, $input);
|
||||
}
|
||||
|
||||
public function provideMessyWhitespacesCases() {
|
||||
return [
|
||||
[
|
||||
"<?php\r\n\$a = \$a;\r\n\r\nreturn \$a;",
|
||||
"<?php\r\n\$a = \$a; return \$a;",
|
||||
],
|
||||
[
|
||||
"<?php\r\n\$b = \$b;\r\n\r\nreturn \$b;",
|
||||
"<?php\r\n\$b = \$b;return \$b;",
|
||||
],
|
||||
[
|
||||
"<?php\r\n\$c = \$c;\r\n\r\nreturn \$c;",
|
||||
"<?php\r\n\$c = \$c;\r\nreturn \$c;",
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
protected function createFixer() {
|
||||
return new BlankLineBeforeReturnFixer();
|
||||
}
|
||||
|
||||
}
|
370
tests/Fixer/Whitespace/LineBreakAfterStatementsFixerTest.php
Normal file
370
tests/Fixer/Whitespace/LineBreakAfterStatementsFixerTest.php
Normal file
@ -0,0 +1,370 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ely\CS\Test\Fixer\Whitespace;
|
||||
|
||||
use Ely\CS\Fixer\Whitespace\LineBreakAfterStatementsFixer;
|
||||
use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
|
||||
|
||||
/**
|
||||
* @covers \Ely\CS\Fixer\Whitespace\LineBreakAfterStatementsFixer
|
||||
*
|
||||
* @author ErickSkrauch <erickskrauch@ely.by>
|
||||
*/
|
||||
class LineBreakAfterStatementsFixerTest extends AbstractFixerTestCase {
|
||||
|
||||
/**
|
||||
* @param string $expected
|
||||
* @param string $input
|
||||
*
|
||||
* @dataProvider provideFixCases
|
||||
*/
|
||||
public function testFix(string $expected, $input = null) {
|
||||
$this->doTest($expected, $input);
|
||||
}
|
||||
|
||||
public function provideFixCases() {
|
||||
$cases = [];
|
||||
|
||||
// Simple cases
|
||||
$cases[] = [
|
||||
'<?php
|
||||
class Foo
|
||||
{
|
||||
public function foo()
|
||||
{
|
||||
if ("a" === "b") {
|
||||
// code
|
||||
}
|
||||
|
||||
$a = "next statement";
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
class Foo
|
||||
{
|
||||
public function foo()
|
||||
{
|
||||
if ("a" === "b") {
|
||||
// code
|
||||
}
|
||||
$a = "next statement";
|
||||
}
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
class Foo
|
||||
{
|
||||
public function foo()
|
||||
{
|
||||
if ("a" === "b") {
|
||||
// code
|
||||
} else {
|
||||
// another code
|
||||
}
|
||||
|
||||
$a = "next statement";
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
class Foo
|
||||
{
|
||||
public function foo()
|
||||
{
|
||||
if ("a" === "b") {
|
||||
// code
|
||||
} else {
|
||||
// another code
|
||||
}
|
||||
$a = "next statement";
|
||||
}
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
class Foo
|
||||
{
|
||||
public function foo()
|
||||
{
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
// code
|
||||
}
|
||||
|
||||
$a = "next statement";
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
class Foo
|
||||
{
|
||||
public function foo()
|
||||
{
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
// code
|
||||
}
|
||||
$a = "next statement";
|
||||
}
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
class Foo
|
||||
{
|
||||
public function foo()
|
||||
{
|
||||
foreach (["foo", "bar"] as $str) {
|
||||
// code
|
||||
}
|
||||
|
||||
$a = "next statement";
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
class Foo
|
||||
{
|
||||
public function foo()
|
||||
{
|
||||
foreach (["foo", "bar"] as $str) {
|
||||
// code
|
||||
}
|
||||
$a = "next statement";
|
||||
}
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
class Foo
|
||||
{
|
||||
public function foo()
|
||||
{
|
||||
while ($i < 10) {
|
||||
// code
|
||||
}
|
||||
|
||||
$a = "next statement";
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
class Foo
|
||||
{
|
||||
public function foo()
|
||||
{
|
||||
while ($i < 10) {
|
||||
// code
|
||||
}
|
||||
$a = "next statement";
|
||||
}
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
class Foo
|
||||
{
|
||||
public function foo()
|
||||
{
|
||||
do {
|
||||
// code
|
||||
} while ($i < 10);
|
||||
|
||||
$a = "next statement";
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
class Foo
|
||||
{
|
||||
public function foo()
|
||||
{
|
||||
do {
|
||||
// code
|
||||
} while ($i < 10);
|
||||
$a = "next statement";
|
||||
}
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
class Foo
|
||||
{
|
||||
public function foo()
|
||||
{
|
||||
switch ("str") {
|
||||
case "a":
|
||||
break;
|
||||
case "b":
|
||||
break;
|
||||
default:
|
||||
// code
|
||||
}
|
||||
|
||||
$a = "next statement";
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
class Foo
|
||||
{
|
||||
public function foo()
|
||||
{
|
||||
switch ("str") {
|
||||
case "a":
|
||||
break;
|
||||
case "b":
|
||||
break;
|
||||
default:
|
||||
// code
|
||||
}
|
||||
$a = "next statement";
|
||||
}
|
||||
}',
|
||||
];
|
||||
// Extended cases
|
||||
$cases[] = [
|
||||
'<?php
|
||||
class Foo
|
||||
{
|
||||
public function bar()
|
||||
{
|
||||
if ("a" === "b") {
|
||||
// code
|
||||
} else if ("a" === "c") {
|
||||
// code
|
||||
} else if ("a" === "d") {
|
||||
// code
|
||||
}
|
||||
|
||||
$a = "next statement";
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
class Foo
|
||||
{
|
||||
public function bar()
|
||||
{
|
||||
if ("a" === "b") {
|
||||
// code
|
||||
} else if ("a" === "c") {
|
||||
// code
|
||||
} else if ("a" === "d") {
|
||||
// code
|
||||
}
|
||||
$a = "next statement";
|
||||
}
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
class Foo
|
||||
{
|
||||
public function bar()
|
||||
{
|
||||
if ("a" === "b") {
|
||||
// code
|
||||
} elseif ("a" === "c") {
|
||||
// code
|
||||
} elseif ("a" === "d") {
|
||||
// code
|
||||
}
|
||||
|
||||
$a = "next statement";
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
class Foo
|
||||
{
|
||||
public function bar()
|
||||
{
|
||||
if ("a" === "b") {
|
||||
// code
|
||||
} elseif ("a" === "c") {
|
||||
// code
|
||||
} elseif ("a" === "d") {
|
||||
// code
|
||||
}
|
||||
$a = "next statement";
|
||||
}
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
class Foo
|
||||
{
|
||||
public function bar()
|
||||
{
|
||||
foreach (["foo", "bar"] as $str) {
|
||||
if ($str === "foo") {
|
||||
// code
|
||||
}
|
||||
}
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
class Foo
|
||||
{
|
||||
public function bar()
|
||||
{
|
||||
foreach (["foo", "bar"] as $str) {
|
||||
if ($str === "foo") {
|
||||
// code
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
class Foo
|
||||
{
|
||||
public function foo()
|
||||
{
|
||||
switch ("str") {
|
||||
case "a": {
|
||||
break;
|
||||
}
|
||||
case "b": {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// code
|
||||
}
|
||||
}
|
||||
|
||||
$a = "next statement";
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
class Foo
|
||||
{
|
||||
public function foo()
|
||||
{
|
||||
switch ("str") {
|
||||
case "a": {
|
||||
break;
|
||||
}
|
||||
case "b": {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// code
|
||||
}
|
||||
}
|
||||
$a = "next statement";
|
||||
}
|
||||
}',
|
||||
];
|
||||
$cases[] = [
|
||||
'<?php
|
||||
$a = "prev statement";
|
||||
foreach ($coordinates as $coordinate) {
|
||||
[$x, $y] = explode(\',\', $coordinate);
|
||||
}
|
||||
',
|
||||
];
|
||||
|
||||
return $cases;
|
||||
}
|
||||
|
||||
protected function createFixer() {
|
||||
return new LineBreakAfterStatementsFixer();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user