Browse Source

Merge branch '2.9'

# Conflicts:
#	tests/AutoReview/FixerFactoryTest.php
Dariusz Ruminski 7 years ago
parent
commit
a5ce78dd6d

+ 1 - 1
README.rst

@@ -359,7 +359,7 @@ Choose from the list of available rules:
 
 * **combine_consecutive_issets**
 
-  Using ``isset(X) &&`` multiple times should be done in one call.
+  Using ``isset($var) &&`` multiple times should be done in one call.
 
 * **combine_consecutive_unsets**
 

+ 30 - 23
src/Differ/DiffConsoleFormatter.php

@@ -53,35 +53,42 @@ final class DiffConsoleFormatter
 
         $template = $isDecorated
             ? $this->template
-            : preg_replace('/<[^<>]+>/', '', $this->template);
+            : preg_replace('/<[^<>]+>/', '', $this->template)
+        ;
 
         return sprintf(
             $template,
-            implode(PHP_EOL, array_map(
-                static function ($string) use ($isDecorated, $lineTemplate) {
-                    if ($isDecorated) {
-                        $string = preg_replace(
-                            ['/^(\+.*)/', '/^(\-.*)/', '/^(@.*)/'],
-                            ['<fg=green>\1</fg=green>', '<fg=red>\1</fg=red>', '<fg=cyan>\1</fg=cyan>'],
-                            $string
-                        );
-                    }
+            implode(
+                PHP_EOL,
+                array_map(
+                    function ($string) use ($isDecorated, $lineTemplate) {
+                        if ($isDecorated) {
+                            $string = preg_replace_callback(
+                                [
+                                    '/^(\+.*)/',
+                                    '/^(\-.*)/',
+                                    '/^(@.*)/',
+                                ],
+                                function ($matches) {
+                                    if ('+' === $matches[0][0]) {
+                                        $colour = 'green';
+                                    } elseif ('-' === $matches[0][0]) {
+                                        $colour = 'red';
+                                    } else {
+                                        $colour = 'cyan';
+                                    }
 
-                    $templated = sprintf($lineTemplate, $string);
+                                    return sprintf('<fg=%s>%s</fg=%s>', $colour, OutputFormatter::escape($matches[0]), $colour);
+                                },
+                                $string
+                            );
+                        }
 
-                    if (' ' === $string) {
-                        $templated = rtrim($templated);
-                    }
-
-                    return $templated;
-                },
-                preg_split(
-                    "#\n\r|\n#",
-                    $isDecorated
-                        ? OutputFormatter::escape(rtrim($diff))
-                        : rtrim($diff)
+                        return sprintf($lineTemplate, $string);
+                    },
+                    preg_split('#\R#u', $diff)
                 )
-            ))
+            )
         );
     }
 }

+ 1 - 1
src/DocBlock/Annotation.php

@@ -217,7 +217,7 @@ class Annotation
      */
     public function setTypes(array $types)
     {
-        $pattern = '/'.preg_quote($this->getTypesContent()).'/';
+        $pattern = '/'.preg_quote($this->getTypesContent(), '/').'/';
 
         $this->lines[0]->setContent(preg_replace($pattern, implode('|', $types), $this->lines[0]->getContent(), 1));
 

+ 3 - 1
src/Fixer/Basic/BracesFixer.php

@@ -411,7 +411,9 @@ class Foo
                         // and it is not a `Foo::{bar}()` situation
                         !($nestToken->equals('}') && $nextNonWhitespaceNestToken->equals('(')) &&
                         // and it is not a `${"a"}->...` and `${"b{$foo}"}->...` situation
-                        !($nestToken->equals('}') && $tokens[$nestIndex - 1]->equalsAny(['"', "'", [T_CONSTANT_ENCAPSED_STRING]]))
+                        !($nestToken->equals('}') && $tokens[$nestIndex - 1]->equalsAny(['"', "'", [T_CONSTANT_ENCAPSED_STRING]])) &&
+                        // and next token is not a closing tag that would break heredoc/nowdoc syntax
+                        !($tokens[$nestIndex - 1]->isGivenKind(T_END_HEREDOC) && $nextNonWhitespaceNestToken->isGivenKind(T_CLOSE_TAG))
                     ) {
                         if (
                             (

+ 1 - 1
src/Fixer/Import/NoUnusedImportsFixer.php

@@ -101,7 +101,7 @@ final class NoUnusedImportsFixer extends AbstractFixer
         $usages = [];
 
         foreach ($useDeclarations as $shortName => $useDeclaration) {
-            $usages[$shortName] = (bool) preg_match('/(?<![\$\\\\])(?<!->)\b'.preg_quote($shortName).'\b/i', $content);
+            $usages[$shortName] = (bool) preg_match('/(?<![\$\\\\])(?<!->)\b'.preg_quote($shortName, '/').'\b/i', $content);
         }
 
         return $usages;

+ 1 - 1
src/Fixer/LanguageConstruct/CombineConsecutiveIssetsFixer.php

@@ -29,7 +29,7 @@ final class CombineConsecutiveIssetsFixer extends AbstractFixer
     public function getDefinition()
     {
         return new FixerDefinition(
-            'Using `isset(X) &&` multiple times should be done in one call.',
+            'Using `isset($var) &&` multiple times should be done in one call.',
             [new CodeSample("<?php\n\$a = isset(\$a) && isset(\$b);\n")]
         );
     }

+ 1 - 1
src/Fixer/Phpdoc/PhpdocAnnotationWithoutDotFixer.php

@@ -88,7 +88,7 @@ function foo ($bar) {}
 
                 $startLine = $doc->getLine($annotation->getStart());
                 $optionalTypeRegEx = $annotation->supportTypes()
-                    ? sprintf('(?:%s\s+(?:\$\w+\s+)?)?', preg_quote(implode('|', $annotation->getTypes())))
+                    ? sprintf('(?:%s\s+(?:\$\w+\s+)?)?', preg_quote(implode('|', $annotation->getTypes()), '/'))
                     : '';
                 $content = preg_replace_callback(
                     '/^(\s*\*\s*@\w+\s+'.$optionalTypeRegEx.')(\p{Lu}?(?=\p{Ll}|\p{Zs}))(.*)$/',

+ 202 - 108
tests/AutoReview/FixerFactoryTest.php

@@ -39,6 +39,7 @@ final class FixerFactoryTest extends TestCase
 
     /**
      * @dataProvider provideFixersPriorityCases
+     * @dataProvider provideFixersPrioritySpecialPhpdocCases
      */
     public function testFixersPriority(FixerInterface $first, FixerInterface $second)
     {
@@ -56,140 +57,154 @@ final class FixerFactoryTest extends TestCase
             $fixers[$fixer->getName()] = $fixer;
         }
 
-        $cases = [
-            [$fixers['array_syntax'], $fixers['binary_operator_spaces']], // tested also in: array_syntax,binary_operator_spaces.test
-            [$fixers['array_syntax'], $fixers['ternary_operator_spaces']], // tested also in: array_syntax,ternary_operator_spaces.test
-            [$fixers['backtick_to_shell_exec'], $fixers['escape_implicit_backslashes']], // tested also in: backtick_to_shell_exec,escape_implicit_backslashes.test
-            [$fixers['blank_line_after_opening_tag'], $fixers['no_blank_lines_before_namespace']], // tested also in: blank_line_after_opening_tag,no_blank_lines_before_namespace.test
+        return [
+            [$fixers['array_syntax'], $fixers['binary_operator_spaces']],
+            [$fixers['array_syntax'], $fixers['ternary_operator_spaces']],
+            [$fixers['backtick_to_shell_exec'], $fixers['escape_implicit_backslashes']],
+            [$fixers['blank_line_after_opening_tag'], $fixers['no_blank_lines_before_namespace']],
             [$fixers['class_attributes_separation'], $fixers['braces']],
             [$fixers['class_attributes_separation'], $fixers['indentation_type']],
-            [$fixers['class_keyword_remove'], $fixers['no_unused_imports']], // tested also in: class_keyword_remove,no_unused_imports.test
-            [$fixers['combine_consecutive_issets'], $fixers['multiline_whitespace_before_semicolons']], // tested also in: combine_consecutive_issets,multiline_whitespace_before_semicolons.test
-            [$fixers['combine_consecutive_issets'], $fixers['no_spaces_inside_parenthesis']], // tested also in: combine_consecutive_issets,no_spaces_inside_parenthesis.test
-            [$fixers['combine_consecutive_issets'], $fixers['no_trailing_whitespace']], // tested also in: combine_consecutive_issets,no_trailing_whitespace.test
-            [$fixers['combine_consecutive_issets'], $fixers['no_whitespace_in_blank_line']], // tested also in: combine_consecutive_issets,no_whitespace_in_blank_line.test
-            [$fixers['combine_consecutive_unsets'], $fixers['no_extra_blank_lines']], // tested also in: combine_consecutive_unsets,no_extra_blank_lines.test
-            [$fixers['combine_consecutive_unsets'], $fixers['no_trailing_whitespace']], // tested also in: combine_consecutive_unsets,no_trailing_whitespace.test
-            [$fixers['combine_consecutive_unsets'], $fixers['no_whitespace_in_blank_line']], // tested also in: combine_consecutive_unsets,no_whitespace_in_blank_line.test
-            [$fixers['combine_consecutive_unsets'], $fixers['space_after_semicolon']], // tested also in: combine_consecutive_unsets,space_after_semicolon.test
-            [$fixers['declare_strict_types'], $fixers['blank_line_after_opening_tag']], // tested also in: declare_strict_types,blank_line_after_opening_tag.test
-            [$fixers['declare_strict_types'], $fixers['declare_equal_normalize']], // tested also in: declare_strict_types,declare_equal_normalize.test
-            [$fixers['declare_strict_types'], $fixers['single_blank_line_before_namespace']], // tested also in: declare_strict_types,single_blank_line_before_namespace.test
+            [$fixers['class_keyword_remove'], $fixers['no_unused_imports']],
+            [$fixers['combine_consecutive_issets'], $fixers['multiline_whitespace_before_semicolons']],
+            [$fixers['combine_consecutive_issets'], $fixers['no_spaces_inside_parenthesis']],
+            [$fixers['combine_consecutive_issets'], $fixers['no_trailing_whitespace']],
+            [$fixers['combine_consecutive_issets'], $fixers['no_whitespace_in_blank_line']],
+            [$fixers['combine_consecutive_unsets'], $fixers['no_extra_blank_lines']],
+            [$fixers['combine_consecutive_unsets'], $fixers['no_trailing_whitespace']],
+            [$fixers['combine_consecutive_unsets'], $fixers['no_whitespace_in_blank_line']],
+            [$fixers['combine_consecutive_unsets'], $fixers['space_after_semicolon']],
+            [$fixers['declare_strict_types'], $fixers['blank_line_after_opening_tag']],
+            [$fixers['declare_strict_types'], $fixers['declare_equal_normalize']],
+            [$fixers['declare_strict_types'], $fixers['single_blank_line_before_namespace']],
             [$fixers['elseif'], $fixers['braces']],
-            [$fixers['escape_implicit_backslashes'], $fixers['heredoc_to_nowdoc']], // tested also in: escape_implicit_backslashes,heredoc_to_nowdoc.test
-            [$fixers['escape_implicit_backslashes'], $fixers['single_quote']], // tested also in: escape_implicit_backslashes,single_quote.test
-            [$fixers['function_to_constant'], $fixers['native_function_casing']], // no priority issue; for speed only
-            [$fixers['function_to_constant'], $fixers['no_extra_blank_lines']], // tested also in: function_to_constant,no_extra_blank_lines.test
-            [$fixers['function_to_constant'], $fixers['no_singleline_whitespace_before_semicolons']], // tested also in: function_to_constant,no_singleline_whitespace_before_semicolons.test
-            [$fixers['function_to_constant'], $fixers['no_trailing_whitespace']], // tested also in: function_to_constant,no_trailing_whitespace.test
-            [$fixers['function_to_constant'], $fixers['no_whitespace_in_blank_line']], // tested also in: function_to_constant,no_whitespace_in_blank_line.test
+            [$fixers['escape_implicit_backslashes'], $fixers['heredoc_to_nowdoc']],
+            [$fixers['escape_implicit_backslashes'], $fixers['single_quote']],
+            [$fixers['function_to_constant'], $fixers['native_function_casing']],
+            [$fixers['function_to_constant'], $fixers['no_extra_blank_lines']],
+            [$fixers['function_to_constant'], $fixers['no_singleline_whitespace_before_semicolons']],
+            [$fixers['function_to_constant'], $fixers['no_trailing_whitespace']],
+            [$fixers['function_to_constant'], $fixers['no_whitespace_in_blank_line']],
             [$fixers['indentation_type'], $fixers['phpdoc_indent']],
-            [$fixers['is_null'], $fixers['yoda_style']], // tested also in: is_null,yoda_style.test
+            [$fixers['is_null'], $fixers['yoda_style']],
             [$fixers['line_ending'], $fixers['single_blank_line_at_eof']],
-            [$fixers['list_syntax'], $fixers['binary_operator_spaces']], // tested also in: list_syntax,binary_operator_spaces.test
-            [$fixers['list_syntax'], $fixers['ternary_operator_spaces']], // tested also in: list_syntax,ternary_operator_spaces.test
+            [$fixers['list_syntax'], $fixers['binary_operator_spaces']],
+            [$fixers['list_syntax'], $fixers['ternary_operator_spaces']],
             [$fixers['method_separation'], $fixers['braces']],
             [$fixers['method_separation'], $fixers['indentation_type']],
-            [$fixers['no_alias_functions'], $fixers['php_unit_dedicate_assert']], // tested also in: no_alias_functions,php_unit_dedicate_assert.test
-            [$fixers['no_blank_lines_after_phpdoc'], $fixers['single_blank_line_before_namespace']], // tested also in: no_blank_lines_after_phpdoc,single_blank_line_before_namespace.test
-            [$fixers['no_empty_comment'], $fixers['no_extra_blank_lines']], // tested also in: no_empty_comment,no_extra_blank_lines.test
-            [$fixers['no_empty_comment'], $fixers['no_trailing_whitespace']], // tested also in: no_empty_comment,no_trailing_whitespace.test
-            [$fixers['no_empty_comment'], $fixers['no_whitespace_in_blank_line']], // tested also in: no_empty_comment,no_whitespace_in_blank_line.test
-            [$fixers['no_empty_phpdoc'], $fixers['no_extra_blank_lines']], // tested also in: no_empty_phpdoc,no_extra_blank_lines.test
-            [$fixers['no_empty_phpdoc'], $fixers['no_trailing_whitespace']], // tested also in: no_empty_phpdoc,no_trailing_whitespace.test
-            [$fixers['no_empty_phpdoc'], $fixers['no_whitespace_in_blank_line']], // tested also in: no_empty_phpdoc,no_whitespace_in_blank_line.test
+            [$fixers['no_alias_functions'], $fixers['php_unit_dedicate_assert']],
+            [$fixers['no_blank_lines_after_phpdoc'], $fixers['single_blank_line_before_namespace']],
+            [$fixers['no_empty_comment'], $fixers['no_extra_blank_lines']],
+            [$fixers['no_empty_comment'], $fixers['no_trailing_whitespace']],
+            [$fixers['no_empty_comment'], $fixers['no_whitespace_in_blank_line']],
+            [$fixers['no_empty_phpdoc'], $fixers['no_extra_blank_lines']],
+            [$fixers['no_empty_phpdoc'], $fixers['no_trailing_whitespace']],
+            [$fixers['no_empty_phpdoc'], $fixers['no_whitespace_in_blank_line']],
             [$fixers['no_empty_statement'], $fixers['braces']],
-            [$fixers['no_empty_statement'], $fixers['combine_consecutive_unsets']], // tested also in: no_empty_statement,combine_consecutive_unsets.test
-            [$fixers['no_empty_statement'], $fixers['no_extra_blank_lines']], // tested also in: no_empty_statement,no_extra_blank_lines.test
+            [$fixers['no_empty_statement'], $fixers['combine_consecutive_unsets']],
+            [$fixers['no_empty_statement'], $fixers['no_extra_blank_lines']],
             [$fixers['no_empty_statement'], $fixers['multiline_whitespace_before_semicolons']],
             [$fixers['no_empty_statement'], $fixers['no_singleline_whitespace_before_semicolons']],
-            [$fixers['no_empty_statement'], $fixers['no_trailing_whitespace']], // tested also in: no_empty_statement,no_trailing_whitespace.test
-            [$fixers['no_empty_statement'], $fixers['no_useless_else']], // tested also in: no_empty_statement,no_useless_else.test
-            [$fixers['no_empty_statement'], $fixers['no_useless_return']], // tested also in: no_empty_statement,no_useless_return.test
-            [$fixers['no_empty_statement'], $fixers['no_whitespace_in_blank_line']], // tested also in: no_empty_statement,no_whitespace_in_blank_line.test
-            [$fixers['no_empty_statement'], $fixers['space_after_semicolon']], // tested also in: no_empty_statement,space_after_semicolon.test
-            [$fixers['no_empty_statement'], $fixers['switch_case_semicolon_to_colon']], // tested also in: no_empty_statement,switch_case_semicolon_to_colon.test
-            [$fixers['no_leading_import_slash'], $fixers['ordered_imports']], // tested also in: no_leading_import_slash,ordered_imports.test
-            [$fixers['no_multiline_whitespace_around_double_arrow'], $fixers['binary_operator_spaces']], // tested also in: no_multiline_whitespace_around_double_arrow,binary_operator_spaces.test
-            [$fixers['no_multiline_whitespace_around_double_arrow'], $fixers['trailing_comma_in_multiline_array']], // tested also in: no_multiline_whitespace_around_double_arrow,trailing_comma_in_multiline_array.test
-            [$fixers['multiline_whitespace_before_semicolons'], $fixers['space_after_semicolon']], // tested also in: tests/Fixtures/Integration/priority/multiline_whitespace_before_semicolons,space_after_semicolon.test
-            [$fixers['no_php4_constructor'], $fixers['ordered_class_elements']], // tested also in: no_php4_constructor,ordered_class_elements.test
-            [$fixers['no_short_bool_cast'], $fixers['cast_spaces']], // tested also in: no_short_bool_cast,cast_spaces.test
-            [$fixers['no_short_echo_tag'], $fixers['no_mixed_echo_print']], // tested also in: no_mixed_echo_print,no_short_echo_tag.test
-            [$fixers['no_spaces_after_function_name'], $fixers['function_to_constant']], // tested also in: no_spaces_after_function_name,function_to_constant.test
-            [$fixers['no_spaces_inside_parenthesis'], $fixers['function_to_constant']], // tested also in: no_spaces_inside_parenthesis,function_to_constant.test
-            [$fixers['no_unneeded_control_parentheses'], $fixers['no_trailing_whitespace']], // tested also in: no_trailing_whitespace,no_unneeded_control_parentheses.test
-            [$fixers['no_unneeded_curly_braces'], $fixers['no_useless_else']], // tested also in: no_unneeded_curly_braces,no_useless_else.test
-            [$fixers['no_unneeded_curly_braces'], $fixers['no_useless_return']], // tested also in: no_unneeded_curly_braces,no_useless_return.test
-            [$fixers['no_unused_imports'], $fixers['blank_line_after_namespace']], // tested also in: no_unused_imports,blank_line_after_namespace.test and no_unused_imports,blank_line_after_namespace_2.test
-            [$fixers['no_unused_imports'], $fixers['no_extra_blank_lines']], // tested also in: no_unused_imports,no_extra_blank_lines.test
-            [$fixers['no_unused_imports'], $fixers['no_leading_import_slash']], // no priority issue; for speed only
+            [$fixers['no_empty_statement'], $fixers['no_trailing_whitespace']],
+            [$fixers['no_empty_statement'], $fixers['no_useless_else']],
+            [$fixers['no_empty_statement'], $fixers['no_useless_return']],
+            [$fixers['no_empty_statement'], $fixers['no_whitespace_in_blank_line']],
+            [$fixers['no_empty_statement'], $fixers['space_after_semicolon']],
+            [$fixers['no_empty_statement'], $fixers['switch_case_semicolon_to_colon']],
+            [$fixers['no_leading_import_slash'], $fixers['ordered_imports']],
+            [$fixers['no_multiline_whitespace_around_double_arrow'], $fixers['binary_operator_spaces']],
+            [$fixers['no_multiline_whitespace_around_double_arrow'], $fixers['trailing_comma_in_multiline_array']],
+            [$fixers['multiline_whitespace_before_semicolons'], $fixers['space_after_semicolon']],
+            [$fixers['no_php4_constructor'], $fixers['ordered_class_elements']],
+            [$fixers['no_short_bool_cast'], $fixers['cast_spaces']],
+            [$fixers['no_short_echo_tag'], $fixers['no_mixed_echo_print']],
+            [$fixers['no_spaces_after_function_name'], $fixers['function_to_constant']],
+            [$fixers['no_spaces_inside_parenthesis'], $fixers['function_to_constant']],
+            [$fixers['no_unneeded_control_parentheses'], $fixers['no_trailing_whitespace']],
+            [$fixers['no_unneeded_curly_braces'], $fixers['no_useless_else']],
+            [$fixers['no_unneeded_curly_braces'], $fixers['no_useless_return']],
+            [$fixers['no_unused_imports'], $fixers['blank_line_after_namespace']],
+            [$fixers['no_unused_imports'], $fixers['no_extra_blank_lines']],
+            [$fixers['no_unused_imports'], $fixers['no_leading_import_slash']],
             [$fixers['no_useless_else'], $fixers['braces']],
-            [$fixers['no_useless_else'], $fixers['combine_consecutive_unsets']], // tested also in: no_useless_else,combine_consecutive_unsets.test
-            [$fixers['no_useless_else'], $fixers['no_extra_blank_lines']], // tested also in: no_useless_else,no_extra_blank_lines.test
-            [$fixers['no_useless_else'], $fixers['no_trailing_whitespace']], // tested also in: no_useless_else,no_trailing_whitespace.test
-            [$fixers['no_useless_else'], $fixers['no_useless_return']], // tested also in: no_useless_else,no_useless_return.test
-            [$fixers['no_useless_else'], $fixers['no_whitespace_in_blank_line']], // tested also in: no_useless_else,no_whitespace_in_blank_line.test
-            [$fixers['no_useless_return'], $fixers['blank_line_before_return']], // tested also in: no_useless_return,blank_line_before_return.test
-            [$fixers['no_useless_return'], $fixers['blank_line_before_statement']], // tested also in: no_useless_return,blank_line_before_statement.test
-            [$fixers['no_useless_return'], $fixers['no_extra_blank_lines']], // tested also in: no_useless_return,no_extra_blank_lines.test
-            [$fixers['no_useless_return'], $fixers['no_whitespace_in_blank_line']], // tested also in: no_useless_return,no_whitespace_in_blank_line.test
-            [$fixers['ordered_class_elements'], $fixers['class_attributes_separation']], // tested also in: ordered_class_elements,class_attributes_separation.test
-            [$fixers['ordered_class_elements'], $fixers['method_separation']], // tested also in: ordered_class_elements,method_separation.test
-            [$fixers['ordered_class_elements'], $fixers['no_blank_lines_after_class_opening']], // tested also in: ordered_class_elements,no_blank_lines_after_class_opening.test
-            [$fixers['ordered_class_elements'], $fixers['space_after_semicolon']], // tested also in: ordered_class_elements,space_after_semicolon.test
-            [$fixers['php_unit_fqcn_annotation'], $fixers['no_unused_imports']], // tested also in: php_unit_fqcn_annotation,unused_use.test
-            [$fixers['php_unit_no_expectation_annotation'], $fixers['no_empty_phpdoc']], // tested also in: php_unit_no_expectation_annotation,no_empty_phpdoc.test
-            [$fixers['php_unit_no_expectation_annotation'], $fixers['php_unit_expectation']], // tested also in: php_unit_no_expectation_annotation,php_unit_expectation.test
+            [$fixers['no_useless_else'], $fixers['combine_consecutive_unsets']],
+            [$fixers['no_useless_else'], $fixers['no_extra_blank_lines']],
+            [$fixers['no_useless_else'], $fixers['no_trailing_whitespace']],
+            [$fixers['no_useless_else'], $fixers['no_useless_return']],
+            [$fixers['no_useless_else'], $fixers['no_whitespace_in_blank_line']],
+            [$fixers['no_useless_return'], $fixers['blank_line_before_return']],
+            [$fixers['no_useless_return'], $fixers['blank_line_before_statement']],
+            [$fixers['no_useless_return'], $fixers['no_extra_blank_lines']],
+            [$fixers['no_useless_return'], $fixers['no_whitespace_in_blank_line']],
+            [$fixers['ordered_class_elements'], $fixers['class_attributes_separation']],
+            [$fixers['ordered_class_elements'], $fixers['method_separation']],
+            [$fixers['ordered_class_elements'], $fixers['no_blank_lines_after_class_opening']],
+            [$fixers['ordered_class_elements'], $fixers['space_after_semicolon']],
+            [$fixers['php_unit_fqcn_annotation'], $fixers['no_unused_imports']],
+            [$fixers['php_unit_no_expectation_annotation'], $fixers['no_empty_phpdoc']],
+            [$fixers['php_unit_no_expectation_annotation'], $fixers['php_unit_expectation']],
             [$fixers['php_unit_strict'], $fixers['php_unit_construct']],
-            [$fixers['phpdoc_add_missing_param_annotation'], $fixers['phpdoc_align']], // tested also in: phpdoc_add_missing_param_annotation,phpdoc_align.test
-            [$fixers['phpdoc_add_missing_param_annotation'], $fixers['phpdoc_order']], // tested also in: phpdoc_add_missing_param_annotation,phpdoc_order.test
-            [$fixers['phpdoc_no_access'], $fixers['no_empty_phpdoc']], // tested also in: phpdoc_no_access,no_empty_phpdoc.test
+            [$fixers['phpdoc_add_missing_param_annotation'], $fixers['phpdoc_align']],
+            [$fixers['phpdoc_add_missing_param_annotation'], $fixers['phpdoc_order']],
+            [$fixers['phpdoc_no_access'], $fixers['no_empty_phpdoc']],
             [$fixers['phpdoc_no_access'], $fixers['phpdoc_order']],
             [$fixers['phpdoc_no_access'], $fixers['phpdoc_separation']],
             [$fixers['phpdoc_no_access'], $fixers['phpdoc_trim']],
-            [$fixers['phpdoc_no_alias_tag'], $fixers['phpdoc_add_missing_param_annotation']], // tested also in: phpdoc_no_alias_tag,phpdoc_add_missing_param_annotation.test
-            [$fixers['phpdoc_no_alias_tag'], $fixers['phpdoc_single_line_var_spacing']], // tested also in: phpdoc_no_alias_tag,phpdoc_single_line_var_spacing.test
-            [$fixers['phpdoc_no_empty_return'], $fixers['no_empty_phpdoc']], // tested also in: phpdoc_no_empty_return,no_empty_phpdoc.test
-            [$fixers['phpdoc_no_empty_return'], $fixers['phpdoc_order']], // tested also in: phpdoc_no_empty_return,phpdoc_separation.test
-            [$fixers['phpdoc_no_empty_return'], $fixers['phpdoc_separation']], // tested also in: phpdoc_no_empty_return,phpdoc_separation.test
+            [$fixers['phpdoc_no_alias_tag'], $fixers['phpdoc_add_missing_param_annotation']],
+            [$fixers['phpdoc_no_alias_tag'], $fixers['phpdoc_single_line_var_spacing']],
+            [$fixers['phpdoc_no_empty_return'], $fixers['no_empty_phpdoc']],
+            [$fixers['phpdoc_no_empty_return'], $fixers['phpdoc_order']],
+            [$fixers['phpdoc_no_empty_return'], $fixers['phpdoc_separation']],
             [$fixers['phpdoc_no_empty_return'], $fixers['phpdoc_trim']],
-            [$fixers['phpdoc_no_package'], $fixers['no_empty_phpdoc']], // tested also in: phpdoc_no_package,no_empty_phpdoc.test
+            [$fixers['phpdoc_no_package'], $fixers['no_empty_phpdoc']],
             [$fixers['phpdoc_no_package'], $fixers['phpdoc_order']],
-            [$fixers['phpdoc_no_package'], $fixers['phpdoc_separation']], // tested also in: phpdoc_no_package,phpdoc_separation.test
+            [$fixers['phpdoc_no_package'], $fixers['phpdoc_separation']],
             [$fixers['phpdoc_no_package'], $fixers['phpdoc_trim']],
-            [$fixers['phpdoc_no_useless_inheritdoc'], $fixers['no_empty_phpdoc']], // tested also in: phpdoc_no_useless_inheritdoc,no_empty_phpdoc.test
-            [$fixers['phpdoc_no_useless_inheritdoc'], $fixers['no_trailing_whitespace_in_comment']], // tested also in: phpdoc_no_useless_inheritdoc,no_trailing_whitespace_in_comment.test
-            [$fixers['phpdoc_no_useless_inheritdoc'], $fixers['phpdoc_inline_tag']], // tested also in: phpdoc_no_useless_inheritdoc,phpdoc_inline_tag.test
+            [$fixers['phpdoc_no_useless_inheritdoc'], $fixers['no_empty_phpdoc']],
+            [$fixers['phpdoc_no_useless_inheritdoc'], $fixers['no_trailing_whitespace_in_comment']],
+            [$fixers['phpdoc_no_useless_inheritdoc'], $fixers['phpdoc_inline_tag']],
             [$fixers['phpdoc_order'], $fixers['phpdoc_separation']],
             [$fixers['phpdoc_order'], $fixers['phpdoc_trim']],
             [$fixers['phpdoc_separation'], $fixers['phpdoc_trim']],
             [$fixers['phpdoc_summary'], $fixers['phpdoc_trim']],
-            [$fixers['phpdoc_to_comment'], $fixers['no_empty_comment']], // tested also in: phpdoc_to_comment,no_empty_comment.test
-            [$fixers['phpdoc_to_comment'], $fixers['phpdoc_no_useless_inheritdoc']], // tested also in: phpdoc_to_comment,phpdoc_no_useless_inheritdoc.test
+            [$fixers['phpdoc_to_comment'], $fixers['no_empty_comment']],
+            [$fixers['phpdoc_to_comment'], $fixers['phpdoc_no_useless_inheritdoc']],
             [$fixers['phpdoc_var_without_name'], $fixers['phpdoc_trim']],
-            [$fixers['pow_to_exponentiation'], $fixers['binary_operator_spaces']], // tested also in: pow_to_exponentiation,binary_operator_spaces.test
-            [$fixers['pow_to_exponentiation'], $fixers['method_argument_space']], // no priority issue; for speed only
-            [$fixers['pow_to_exponentiation'], $fixers['native_function_casing']], // no priority issue; for speed only
-            [$fixers['pow_to_exponentiation'], $fixers['no_spaces_after_function_name']], // no priority issue; for speed only
-            [$fixers['pow_to_exponentiation'], $fixers['no_spaces_inside_parenthesis']], // no priority issue; for speed only
-            [$fixers['protected_to_private'], $fixers['ordered_class_elements']], // tested also in: protected_to_private,ordered_class_elements.test
-            [$fixers['simplified_null_return'], $fixers['no_useless_return']], // tested also in: simplified_null_return,no_useless_return.test
-            [$fixers['single_import_per_statement'], $fixers['no_leading_import_slash']], // tested also in: single_import_per_statement,no_leading_import_slash.test
-            [$fixers['single_import_per_statement'], $fixers['multiline_whitespace_before_semicolons']], // single_import_per_statement,multiline_whitespace_before_semicolons.test
-            [$fixers['single_import_per_statement'], $fixers['no_singleline_whitespace_before_semicolons']], // tested also in: single_import_per_statement,no_singleline_whitespace_before_semicolons.test
-            [$fixers['single_import_per_statement'], $fixers['no_unused_imports']], // tested also in: single_import_per_statement,no_unused_imports.test
-            [$fixers['single_import_per_statement'], $fixers['ordered_imports']], // tested also in: single_import_per_statement,ordered_imports.test
-            [$fixers['single_import_per_statement'], $fixers['space_after_semicolon']], // tested also in: single_import_per_statement,space_after_semicolon.test
-            [$fixers['standardize_not_equals'], $fixers['binary_operator_spaces']], // tested also in: standardize_not_equals,binary_operator_spaces.test
-            [$fixers['strict_comparison'], $fixers['binary_operator_spaces']], // tested also in: strict_comparison,binary_operator_spaces.text
+            [$fixers['pow_to_exponentiation'], $fixers['binary_operator_spaces']],
+            [$fixers['pow_to_exponentiation'], $fixers['method_argument_space']],
+            [$fixers['pow_to_exponentiation'], $fixers['native_function_casing']],
+            [$fixers['pow_to_exponentiation'], $fixers['no_spaces_after_function_name']],
+            [$fixers['pow_to_exponentiation'], $fixers['no_spaces_inside_parenthesis']],
+            [$fixers['protected_to_private'], $fixers['ordered_class_elements']],
+            [$fixers['simplified_null_return'], $fixers['no_useless_return']],
+            [$fixers['single_import_per_statement'], $fixers['no_leading_import_slash']],
+            [$fixers['single_import_per_statement'], $fixers['multiline_whitespace_before_semicolons']],
+            [$fixers['single_import_per_statement'], $fixers['no_singleline_whitespace_before_semicolons']],
+            [$fixers['single_import_per_statement'], $fixers['no_unused_imports']],
+            [$fixers['single_import_per_statement'], $fixers['ordered_imports']],
+            [$fixers['single_import_per_statement'], $fixers['space_after_semicolon']],
+            [$fixers['standardize_not_equals'], $fixers['binary_operator_spaces']],
+            [$fixers['strict_comparison'], $fixers['binary_operator_spaces']],
             [$fixers['unary_operator_spaces'], $fixers['not_operator_with_space']],
             [$fixers['unary_operator_spaces'], $fixers['not_operator_with_successor_space']],
-            [$fixers['void_return'], $fixers['phpdoc_no_empty_return']], // tested also in: void_return,phpdoc_no_empty_return.test
-            [$fixers['void_return'], $fixers['return_type_declaration']], // tested also in: void_return,return_type_declaration.test
-            [$fixers['php_unit_test_annotation'], $fixers['no_empty_phpdoc']], // tested also in: php_unit_test_annotation,no_empty_phpdoc.test
-            [$fixers['php_unit_test_annotation'], $fixers['phpdoc_trim']], // tested also in: php_unit_test_annotation,phpdoc_trim.test
+            [$fixers['void_return'], $fixers['phpdoc_no_empty_return']],
+            [$fixers['void_return'], $fixers['return_type_declaration']],
+            [$fixers['php_unit_test_annotation'], $fixers['no_empty_phpdoc']],
+            [$fixers['php_unit_test_annotation'], $fixers['phpdoc_trim']],
         ];
+    }
+
+    public function provideFixersPrioritySpecialPhpdocCases()
+    {
+        $factory = new FixerFactory();
+        $factory->registerBuiltInFixers();
+
+        $fixers = [];
+
+        foreach ($factory->getFixers() as $fixer) {
+            $fixers[$fixer->getName()] = $fixer;
+        }
+
+        $cases = [];
 
         // prepare bulk tests for phpdoc fixers to test that:
         // * `phpdoc_to_comment` is first
@@ -223,4 +238,83 @@ final class FixerFactoryTest extends TestCase
 
         return $cases;
     }
+
+    /**
+     * @dataProvider provideFixersPriorityPairsHaveIntegrationTestCases
+     */
+    public function testFixersPriorityPairsHaveIntegrationTest(FixerInterface $first, FixerInterface $second)
+    {
+        // This structure contains older cases that are not yet covered by tests.
+        // It may only shrink, never add anything to it.
+        $casesWithoutTests = [
+            'class_attributes_separation,braces.test',
+            'class_attributes_separation,indentation_type.test',
+            'elseif,braces.test',
+            'indentation_type,phpdoc_indent.test',
+            'line_ending,single_blank_line_at_eof.test',
+            'method_separation,braces.test',
+            'method_separation,indentation_type.test',
+            'no_empty_statement,braces.test',
+            'no_empty_statement,multiline_whitespace_before_semicolons.test',
+            'no_empty_statement,no_multiline_whitespace_before_semicolons.test',
+            'no_empty_statement,no_singleline_whitespace_before_semicolons.test',
+            'no_useless_else,braces.test',
+            'php_unit_strict,php_unit_construct.test',
+            'phpdoc_no_access,phpdoc_order.test',
+            'phpdoc_no_access,phpdoc_separation.test',
+            'phpdoc_no_access,phpdoc_trim.test',
+            'phpdoc_no_empty_return,phpdoc_trim.test',
+            'phpdoc_no_package,phpdoc_order.test',
+            'phpdoc_no_package,phpdoc_trim.test',
+            'phpdoc_order,phpdoc_separation.test',
+            'phpdoc_order,phpdoc_trim.test',
+            'phpdoc_separation,phpdoc_trim.test',
+            'phpdoc_summary,phpdoc_trim.test',
+            'phpdoc_var_without_name,phpdoc_trim.test',
+            'strict_comparison,binary_operator_spaces.test',
+            'unary_operator_spaces,not_operator_with_space.test',
+            'unary_operator_spaces,not_operator_with_successor_space.test',
+        ];
+
+        $integrationTestExists = $this->doesIntegrationTestExist($first, $second);
+
+        if (in_array($this->generateIntegrationTestName($first, $second), $casesWithoutTests, true)) {
+            $this->assertFalse($integrationTestExists, sprintf('Case "%s" already has an integration test, so it should be removed from "$casesWithoutTests".', $this->generateIntegrationTestName($first, $second)));
+            $this->markTestIncomplete(sprintf('Case "%s" has no integration test yet, please help and add it.', $this->generateIntegrationTestName($first, $second)));
+        }
+
+        $this->assertTrue($integrationTestExists, sprintf('There shall be an integration test "%s". How do you know that priority set up is good, if there is no integration test to check it?', $this->generateIntegrationTestName($first, $second)));
+    }
+
+    public function provideFixersPriorityPairsHaveIntegrationTestCases()
+    {
+        return array_filter(
+            $this->provideFixersPriorityCases(),
+            // ignore speed-up only priorities set up
+            function (array $case) {
+                return !in_array(
+                    $this->generateIntegrationTestName($case[0], $case[1]),
+                    [
+                        'function_to_constant,native_function_casing.test',
+                        'no_unused_imports,no_leading_import_slash.test',
+                        'pow_to_exponentiation,method_argument_space.test',
+                        'pow_to_exponentiation,native_function_casing.test',
+                        'pow_to_exponentiation,no_spaces_after_function_name.test',
+                        'pow_to_exponentiation,no_spaces_inside_parenthesis.test',
+                    ],
+                    true
+                );
+            }
+        );
+    }
+
+    private function generateIntegrationTestName(FixerInterface $first, FixerInterface $second)
+    {
+        return "{$first->getName()},{$second->getName()}.test";
+    }
+
+    private function doesIntegrationTestExist(FixerInterface $first, FixerInterface $second)
+    {
+        return is_file(__DIR__.'/../Fixtures/Integration/priority/'.$this->generateIntegrationTestName($first, $second)) || is_file(__DIR__.'/../Fixtures/Integration/priority/'.$this->generateIntegrationTestName($second, $first));
+    }
 }

+ 0 - 1
tests/AutoReview/ProjectCodeTest.php

@@ -40,7 +40,6 @@ final class ProjectCodeTest extends TestCase
         \PhpCsFixer\Console\Output\NullOutput::class,
         \PhpCsFixer\Console\SelfUpdate\GithubClient::class,
         \PhpCsFixer\Console\WarningsDetector::class,
-        \PhpCsFixer\Differ\DiffConsoleFormatter::class,
         \PhpCsFixer\Doctrine\Annotation\Tokens::class,
         \PhpCsFixer\FileRemoval::class,
         \PhpCsFixer\Fixer\Operator\AlignDoubleArrowFixerHelper::class,

+ 10 - 10
tests/Console/Command/DescribeCommandTest.php

@@ -46,8 +46,8 @@ final class DescribeCommandTest extends TestCase
 
     public function testExecuteOutput()
     {
-        $expected = <<<'EOT'
-Description of Foo/bar rule.
+        $expected =
+"Description of Foo/bar rule.
 Fixes stuff. DEPRECATED: use `Foo/baz` instead.
 Replaces bad stuff with good stuff.
 
@@ -65,6 +65,7 @@ Fixing examples:
    @@ -1 +1 @@
    -<?php echo 'bad stuff and bad thing';
    +<?php echo 'good stuff and bad thing';
+   "."
    ----------- end diff -----------
 
  * Example #2. Fixing with configuration: ['functions' => ['foo', 'bar']].
@@ -74,18 +75,17 @@ Fixing examples:
    @@ -1 +1 @@
    -<?php echo 'bad stuff and bad thing';
    +<?php echo 'good stuff and good thing';
+   ".'
    ----------- end diff -----------
 
-
-EOT;
-
+';
         $this->assertSame($expected, $this->execute('Foo/bar', false)->getDisplay(true));
     }
 
     public function testExecuteOutputWithDecoration()
     {
-        $expected = <<<EOT
-\033[32mDescription of\033[39m Foo/bar \033[32mrule\033[39m.
+        $expected =
+"\033[32mDescription of\033[39m Foo/bar \033[32mrule\033[39m.
 Fixes stuff. \033[37;41mDEPRECATED\033[39;49m: use \033[32m`Foo/baz`\033[39m instead.
 Replaces bad stuff with good stuff.
 
@@ -103,6 +103,7 @@ Fixing examples:
    \033[36m@@ -1 +1 @@\033[39m
    \033[31m-<?php echo 'bad stuff and bad thing';\033[39m
    \033[32m+<?php echo 'good stuff and bad thing';\033[39m
+   "."
 \033[33m   ----------- end diff -----------\033[39m
 
  * Example #2. Fixing with configuration: \033[33m['functions' => ['foo', 'bar']]\033[39m.
@@ -112,11 +113,10 @@ Fixing examples:
    \033[36m@@ -1 +1 @@\033[39m
    \033[31m-<?php echo 'bad stuff and bad thing';\033[39m
    \033[32m+<?php echo 'good stuff and good thing';\033[39m
+   "."
 \033[33m   ----------- end diff -----------\033[39m
 
-
-EOT;
-
+";
         $actual = $this->execute('Foo/bar', true)->getDisplay(true);
 
         $this->assertSame($expected, $actual);

Some files were not shown because too many files changed in this diff