Browse Source

Add the 'none' sort algorithm to OrderedImportsFixer

Evgeny Orekhov 7 years ago
parent
commit
20121a6a96
3 changed files with 166 additions and 8 deletions
  1. 3 2
      README.rst
  2. 27 5
      src/Fixer/Import/OrderedImportsFixer.php
  3. 136 1
      tests/Fixer/Import/OrderedImportsFixerTest.php

+ 3 - 2
README.rst

@@ -1042,8 +1042,9 @@ Choose from the list of available rules:
 
   - ``importsOrder`` (``array``, ``null``): defines the order of import types; defaults
     to ``null``
-  - ``sortAlgorithm`` (``'alpha'``, ``'length'``): whether the statements should be
-    sorted alphabetically or by length; defaults to ``'alpha'``
+  - ``sortAlgorithm`` (``'alpha'``, ``'length'``, ``'none'``): whether the statements should
+    be sorted alphabetically or by length, or not sorted; defaults to
+    ``'alpha'``
 
 * **php_unit_construct** [@Symfony:risky]
 

+ 27 - 5
src/Fixer/Import/OrderedImportsFixer.php

@@ -47,6 +47,8 @@ final class OrderedImportsFixer extends AbstractFixer implements ConfigurationDe
 
     const SORT_LENGTH = 'length';
 
+    const SORT_NONE = 'none';
+
     /**
      * Array of supported sort types in configuration.
      *
@@ -59,7 +61,7 @@ final class OrderedImportsFixer extends AbstractFixer implements ConfigurationDe
      *
      * @var string[]
      */
-    private $supportedSortAlgorithms = [self::SORT_ALPHA, self::SORT_LENGTH];
+    private $supportedSortAlgorithms = [self::SORT_ALPHA, self::SORT_LENGTH, self::SORT_NONE];
 
     /**
      * {@inheritdoc}
@@ -127,6 +129,28 @@ use function CCC\AA;
                         ],
                     ]
                 ),
+                new VersionSpecificCodeSample(
+                    '<?php
+use const BBB;
+use const AAAA;
+
+use function DDD;
+use function CCC\AA;
+
+use Acme;
+use AAC;
+use Bar;
+',
+                    new VersionSpecification(70000),
+                    [
+                        'sortAlgorithm' => self::SORT_NONE,
+                        'importsOrder' => [
+                            self::IMPORT_TYPE_CONST,
+                            self::IMPORT_TYPE_CLASS,
+                            self::IMPORT_TYPE_FUNCTION,
+                        ],
+                    ]
+                ),
             ]
         );
     }
@@ -204,7 +228,7 @@ use function CCC\AA;
         $supportedSortTypes = $this->supportedSortTypes;
 
         return new FixerConfigurationResolver([
-            (new FixerOptionBuilder('sortAlgorithm', 'whether the statements should be sorted alphabetically or by length'))
+            (new FixerOptionBuilder('sortAlgorithm', 'whether the statements should be sorted alphabetically or by length, or not sorted'))
                 ->setAllowedValues($this->supportedSortAlgorithms)
                 ->setDefault(self::SORT_ALPHA)
                 ->getOption(),
@@ -327,7 +351,7 @@ use function CCC\AA;
                 $token = $tokens[$index];
 
                 if ($index === $endIndex || (!$group && $token->equals(','))) {
-                    if ($group) {
+                    if ($group && self::SORT_NONE !== $this->configuration['sortAlgorithm']) {
                         // if group import, sort the items within the group definition
 
                         // figure out where the list of namespace parts within the group def. starts
@@ -478,8 +502,6 @@ use function CCC\AA;
             uasort($indexes, [$this, 'sortAlphabetically']);
         } elseif (self::SORT_LENGTH === $this->configuration['sortAlgorithm']) {
             uasort($indexes, [$this, 'sortByLength']);
-        } else {
-            throw new \LogicException(sprintf('Sort algorithm "%s" is not supported.', $this->configuration['sortAlgorithm']));
         }
 
         return $indexes;

+ 136 - 1
tests/Fixer/Import/OrderedImportsFixerTest.php

@@ -814,7 +814,7 @@ use Foo\Bor\{
     {
         $this->expectException(\PhpCsFixer\ConfigurationException\InvalidFixerConfigurationException::class);
         $this->expectExceptionMessage(sprintf(
-            '[ordered_imports] Invalid configuration: The option "sortAlgorithm" with value %s is invalid. Accepted values are: "alpha", "length".',
+            '[ordered_imports] Invalid configuration: The option "sortAlgorithm" with value %s is invalid. Accepted values are: "alpha", "length", "none".',
             $expectedValue
         ));
 
@@ -1700,6 +1700,77 @@ use function some\a\{fn_a, fn_b};
         ];
     }
 
+    /**
+     * @dataProvider provideFix70TypesOrderAndNoneCases
+     * @requires PHP 7.0
+     *
+     * @param string      $expected
+     * @param null|string $input
+     * @param string[]    $importOrder
+     */
+    public function testFix70TypesOrderAndNone($expected, $input = null, array $importOrder = null)
+    {
+        $this->fixer->configure([
+            'sortAlgorithm' => OrderedImportsFixer::SORT_NONE,
+            'importsOrder' => $importOrder,
+        ]);
+
+        $this->doTest($expected, $input);
+    }
+
+    public function provideFix70TypesOrderAndNoneCases()
+    {
+        return [
+            [
+                '<?php
+use Aaa\Ccc;
+use Foo\Zar\Baz;
+use some\a\{ClassA};
+use some\b\{ClassD, ClassB, ClassC as C};
+use Bar\Biz\Boooz\Bum;
+use some\b\{
+    ClassF,
+    ClassG
+};
+use Some\Cloz;
+use Aaa\Bbb;
+use const some\a\{ConstD};
+use const some\a\{ConstA};
+use const some\a\{ConstB, ConstC as CC};
+use const some\b\{ConstE};
+use function some\f\{fn_g, fn_h, fn_i};
+use function some\c\{fn_f};
+use function some\a\{fn};
+use function some\b\{fn_c, fn_d, fn_e};
+use function some\a\{fn_a, fn_b};
+',
+                '<?php
+use Aaa\Ccc;
+use Foo\Zar\Baz;
+use function some\f\{fn_g, fn_h, fn_i};
+use some\a\{ClassA};
+use some\b\{ClassD, ClassB, ClassC as C};
+use Bar\Biz\Boooz\Bum;
+use function some\c\{fn_f};
+use some\b\{
+    ClassF,
+    ClassG
+};
+use const some\a\{ConstD};
+use Some\Cloz;
+use function some\a\{fn};
+use const some\a\{ConstA};
+use function some\b\{fn_c, fn_d, fn_e};
+use const some\a\{ConstB, ConstC as CC};
+use Aaa\Bbb;
+use const some\b\{ConstE};
+use function some\a\{fn_a, fn_b};
+',
+                [OrderedImportsFixer::IMPORT_TYPE_CLASS, OrderedImportsFixer::IMPORT_TYPE_CONST, OrderedImportsFixer::IMPORT_TYPE_FUNCTION],
+            ],
+        ];
+    }
+
     /**
      * @param string      $expected
      * @param null|string $input
@@ -1767,6 +1838,70 @@ use function some\a\{fn_a, fn_b, fn_c,};
                     'importsOrder' => [OrderedImportsFixer::IMPORT_TYPE_CLASS, OrderedImportsFixer::IMPORT_TYPE_CONST, OrderedImportsFixer::IMPORT_TYPE_FUNCTION],
                 ],
             ],
+            [
+                '<?php use A\{B,};
+use some\y\{ClassA, ClassB, ClassC as C,};
+use C\{D,E,};
+use const some\Z\{ConstAA,ConstBB,ConstCC,};
+use const some\X\{ConstA,ConstB,ConstC,ConstF};
+use function some\a\{fn_a, fn_b, fn_c,};
+',
+                $input,
+                [
+                    'sortAlgorithm' => OrderedImportsFixer::SORT_NONE,
+                    'importsOrder' => [OrderedImportsFixer::IMPORT_TYPE_CLASS, OrderedImportsFixer::IMPORT_TYPE_CONST, OrderedImportsFixer::IMPORT_TYPE_FUNCTION],
+                ],
+            ],
         ];
     }
+
+    public function testFixByNone()
+    {
+        $this->fixer->configure([
+            'sortAlgorithm' => OrderedImportsFixer::SORT_NONE,
+            'importsOrder' => null,
+        ]);
+
+        $expected = <<<'EOF'
+The normal
+use of this fixer
+should not change this sentence nor those statements below
+use Zoo\Bar as ZooBar;
+use Foo\Bar;
+use Foo\Zar\Baz;
+
+<?php
+
+use Foo\Bar\FooBar as FooBaz;
+use Zoo\Bar as ZooBar, Zoo\Tar;
+ use Foo\Bar;
+use Foo\Zar\Baz;
+use Symfony\Annotation\Template;
+   use Foo\Bar\Foo as Fooo, Foo\Bir as FBB;
+use SomeClass;
+
+$a = new Bar();
+$a = new FooBaz();
+$a = new someclass();
+
+use Symfony\Doctrine\Entities\Entity;
+
+class AnnotatedClass
+{
+    /**
+     * @Template(foobar=21)
+     * @param Entity $foo
+     */
+    public function doSomething($foo)
+    {
+        $bar = $foo->toArray();
+        /** @var ArrayInterface $bar */
+
+        return function () use ($bar, $foo) {};
+    }
+}
+EOF;
+
+        $this->doTest($expected);
+    }
 }