Browse Source

FileFilterIterator - input checks and utests

SpacePossum 7 years ago
parent
commit
f06a457f7a

+ 1 - 1
src/ConfigInterface.php

@@ -37,7 +37,7 @@ interface ConfigInterface
     /**
      * Returns files to scan.
      *
-     * @return iterable|string[]|\Traversable
+     * @return iterable|\Traversable
      */
     public function getFinder();
 

+ 20 - 2
src/Runner/FileFilterIterator.php

@@ -53,6 +53,15 @@ final class FileFilterIterator extends \FilterIterator
     public function accept()
     {
         $file = $this->current();
+        if (!$file instanceof \SplFileInfo) {
+            throw new \RuntimeException(
+                sprintf(
+                    'Expected instance of "\SplFileInfo", got "%s".',
+                    is_object($file) ? get_class($file) : gettype($file)
+                )
+            );
+        }
+
         $path = $file->getRealPath();
 
         if (isset($this->visitedElements[$path])) {
@@ -61,11 +70,20 @@ final class FileFilterIterator extends \FilterIterator
 
         $this->visitedElements[$path] = true;
 
-        if ($file->isDir() || $file->isLink()) {
+        if (!$file->isFile() || $file->isLink()) {
             return false;
         }
 
-        $content = file_get_contents($path);
+        $content = @file_get_contents($path);
+        if (false === $content) {
+            $error = error_get_last();
+
+            throw new \RuntimeException(sprintf(
+                'Failed to read content from "%s".%s',
+                $path,
+                $error ? ' '.$error['message'] : ''
+            ));
+        }
 
         // mark as skipped:
         if (

+ 0 - 1
tests/AutoReview/ProjectCodeTest.php

@@ -54,7 +54,6 @@ final class ProjectCodeTest extends TestCase
         'PhpCsFixer\PharChecker',
         'PhpCsFixer\Report\ReportSummary',
         'PhpCsFixer\Runner\FileCachingLintingIterator',
-        'PhpCsFixer\Runner\FileFilterIterator',
         'PhpCsFixer\Runner\FileLintingIterator',
         'PhpCsFixer\StdinFileInfo',
         'PhpCsFixer\Tokenizer\Transformers',

+ 0 - 0
tests/Fixtures/empty.php


+ 189 - 0
tests/Runner/FileFilterIteratorTest.php

@@ -0,0 +1,189 @@
+<?php
+
+/*
+ * This file is part of PHP CS Fixer.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *     Dariusz Rumiński <dariusz.ruminski@gmail.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace PhpCsFixer\Tests\Runner;
+
+use PhpCsFixer\FixerFileProcessedEvent;
+use PhpCsFixer\Runner\FileFilterIterator;
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\EventDispatcher\EventDispatcher;
+
+/**
+ * @author SpacePossum
+ *
+ * @internal
+ *
+ * @covers \PhpCsFixer\Runner\FileFilterIterator
+ */
+final class FileFilterIteratorTest extends TestCase
+{
+    /**
+     * @param int $repeat
+     *
+     * @testWith [1]
+     *           [2]
+     *           [3]
+     */
+    public function testAccept($repeat)
+    {
+        $file = __FILE__;
+        $content = file_get_contents($file);
+        $events = array();
+
+        $eventDispatcher = new EventDispatcher();
+        $eventDispatcher->addListener(
+            FixerFileProcessedEvent::NAME,
+            function ($event) use (&$events) {
+                $events[] = $event;
+            }
+        );
+
+        $cache = $this->prophesize('PhpCsFixer\Cache\CacheManagerInterface');
+        $cache->needFixing($file, $content)->willReturn(true);
+
+        $fileInfo = new \SplFileInfo($file);
+
+        $filter = new FileFilterIterator(
+            new \ArrayIterator(array_fill(0, $repeat, $fileInfo)),
+            $eventDispatcher,
+            $cache->reveal()
+        );
+
+        $this->assertCount(0, $events);
+
+        $files = iterator_to_array($filter);
+
+        $this->assertCount(1, $files);
+        $this->assertSame($fileInfo, reset($files));
+    }
+
+    public function testEmitSkipEventWhenCacheNeedFixingFalse()
+    {
+        $file = __FILE__;
+        $content = file_get_contents($file);
+        $events = array();
+
+        $eventDispatcher = new EventDispatcher();
+        $eventDispatcher->addListener(
+            FixerFileProcessedEvent::NAME,
+            function ($event) use (&$events) {
+                $events[] = $event;
+            }
+        );
+
+        $cache = $this->prophesize('PhpCsFixer\Cache\CacheManagerInterface');
+        $cache->needFixing($file, $content)->willReturn(false);
+
+        $filter = new FileFilterIterator(
+            new \ArrayIterator(array(new \SplFileInfo($file))),
+            $eventDispatcher,
+            $cache->reveal()
+        );
+
+        $this->assertCount(0, $filter);
+        $this->assertCount(1, $events);
+
+        /** @var FixerFileProcessedEvent $event */
+        $event = reset($events);
+
+        $this->assertInstanceOf('PhpCsFixer\FixerFileProcessedEvent', $event);
+        $this->assertSame(FixerFileProcessedEvent::STATUS_SKIPPED, $event->getStatus());
+    }
+
+    public function testIgnoreEmptyFile()
+    {
+        $file = __DIR__.'/../Fixtures/empty.php';
+        $content = file_get_contents($file);
+        $events = array();
+
+        $eventDispatcher = new EventDispatcher();
+        $eventDispatcher->addListener(
+            FixerFileProcessedEvent::NAME,
+            function ($event) use (&$events) {
+                $events[] = $event;
+            }
+        );
+
+        $cache = $this->prophesize('PhpCsFixer\Cache\CacheManagerInterface');
+        $cache->needFixing($file, $content)->willReturn(true);
+
+        $filter = new FileFilterIterator(
+            new \ArrayIterator(array(new \SplFileInfo($file))),
+            $eventDispatcher,
+            $cache->reveal()
+        );
+
+        $this->assertCount(0, $filter);
+        $this->assertCount(1, $events);
+
+        /** @var FixerFileProcessedEvent $event */
+        $event = reset($events);
+
+        $this->assertInstanceOf('PhpCsFixer\FixerFileProcessedEvent', $event);
+        $this->assertSame(FixerFileProcessedEvent::STATUS_SKIPPED, $event->getStatus());
+    }
+
+    public function testIgnore()
+    {
+        $eventDispatcher = new EventDispatcher();
+        $eventDispatcher->addListener(
+            FixerFileProcessedEvent::NAME,
+            function () {
+                throw new \Exception('No event expected.');
+            }
+        );
+
+        $filter = new FileFilterIterator(
+            new \ArrayIterator(array(
+                new \SplFileInfo(__DIR__),
+                new \SplFileInfo('__INVALID__'),
+            )),
+            $eventDispatcher,
+            $this->prophesize('PhpCsFixer\Cache\CacheManagerInterface')->reveal()
+        );
+
+        $this->assertCount(0, $filter);
+    }
+
+    public function testWithoutDispatcher()
+    {
+        $file = __FILE__;
+        $content = file_get_contents($file);
+
+        $cache = $this->prophesize('PhpCsFixer\Cache\CacheManagerInterface');
+        $cache->needFixing($file, $content)->willReturn(false);
+
+        $filter = new FileFilterIterator(
+            new \ArrayIterator(array(new \SplFileInfo($file))),
+            null,
+            $cache->reveal()
+        );
+
+        $this->assertCount(0, $filter);
+    }
+
+    public function testInvalidIterator()
+    {
+        $filter = new FileFilterIterator(
+            new \ArrayIterator(array(__FILE__)),
+            null,
+            $this->prophesize('PhpCsFixer\Cache\CacheManagerInterface')->reveal()
+        );
+
+        $this->setExpectedExceptionRegExp(
+            'RuntimeException',
+            '#^Expected instance of "\\\SplFileInfo", got "string"\.$#'
+        );
+
+        iterator_to_array($filter);
+    }
+}