4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\Finder\Tests;
14 use Symfony\Component\Finder\Adapter\AdapterInterface;
15 use Symfony\Component\Finder\Adapter\GnuFindAdapter;
16 use Symfony\Component\Finder\Adapter\PhpAdapter;
17 use Symfony\Component\Finder\Finder;
19 class FinderTest extends Iterator\RealIteratorTestCase
21 public function testCreate()
23 $this->assertInstanceOf('Symfony\Component\Finder\Finder', Finder::create());
26 public function testDirectories()
28 $finder = $this->buildFinder();
29 $this->assertSame($finder, $finder->directories());
30 $this->assertIterator($this->toAbsolute(array('foo', 'toto')), $finder->in(self::$tmpDir)->getIterator());
32 $finder = $this->buildFinder();
33 $finder->directories();
35 $finder->directories();
36 $this->assertIterator($this->toAbsolute(array('foo', 'toto')), $finder->in(self::$tmpDir)->getIterator());
39 public function testFiles()
41 $finder = $this->buildFinder();
42 $this->assertSame($finder, $finder->files());
43 $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'test.py', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
45 $finder = $this->buildFinder();
47 $finder->directories();
49 $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'test.py', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
52 public function testDepth()
54 $finder = $this->buildFinder();
55 $this->assertSame($finder, $finder->depth('< 1'));
56 $this->assertIterator($this->toAbsolute(array('foo', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
58 $finder = $this->buildFinder();
59 $this->assertSame($finder, $finder->depth('<= 0'));
60 $this->assertIterator($this->toAbsolute(array('foo', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
62 $finder = $this->buildFinder();
63 $this->assertSame($finder, $finder->depth('>= 1'));
64 $this->assertIterator($this->toAbsolute(array('foo/bar.tmp')), $finder->in(self::$tmpDir)->getIterator());
66 $finder = $this->buildFinder();
67 $finder->depth('< 1')->depth('>= 1');
68 $this->assertIterator(array(), $finder->in(self::$tmpDir)->getIterator());
71 public function testName()
73 $finder = $this->buildFinder();
74 $this->assertSame($finder, $finder->name('*.php'));
75 $this->assertIterator($this->toAbsolute(array('test.php')), $finder->in(self::$tmpDir)->getIterator());
77 $finder = $this->buildFinder();
78 $finder->name('test.ph*');
79 $finder->name('test.py');
80 $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
82 $finder = $this->buildFinder();
83 $finder->name('~^test~i');
84 $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
86 $finder = $this->buildFinder();
87 $finder->name('~\\.php$~i');
88 $this->assertIterator($this->toAbsolute(array('test.php')), $finder->in(self::$tmpDir)->getIterator());
90 $finder = $this->buildFinder();
91 $finder->name('test.p{hp,y}');
92 $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
95 public function testNotName()
97 $finder = $this->buildFinder();
98 $this->assertSame($finder, $finder->notName('*.php'));
99 $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
101 $finder = $this->buildFinder();
102 $finder->notName('*.php');
103 $finder->notName('*.py');
104 $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
106 $finder = $this->buildFinder();
107 $finder->name('test.ph*');
108 $finder->name('test.py');
109 $finder->notName('*.php');
110 $finder->notName('*.py');
111 $this->assertIterator(array(), $finder->in(self::$tmpDir)->getIterator());
113 $finder = $this->buildFinder();
114 $finder->name('test.ph*');
115 $finder->name('test.py');
116 $finder->notName('*.p{hp,y}');
117 $this->assertIterator(array(), $finder->in(self::$tmpDir)->getIterator());
121 * @dataProvider getRegexNameTestData
123 public function testRegexName($regex)
125 $finder = $this->buildFinder();
126 $finder->name($regex);
127 $this->assertIterator($this->toAbsolute(array('test.py', 'test.php')), $finder->in(self::$tmpDir)->getIterator());
130 public function testSize()
132 $finder = $this->buildFinder();
133 $this->assertSame($finder, $finder->files()->size('< 1K')->size('> 500'));
134 $this->assertIterator($this->toAbsolute(array('test.php')), $finder->in(self::$tmpDir)->getIterator());
137 public function testDate()
139 $finder = $this->buildFinder();
140 $this->assertSame($finder, $finder->files()->date('until last month'));
141 $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php')), $finder->in(self::$tmpDir)->getIterator());
144 public function testExclude()
146 $finder = $this->buildFinder();
147 $this->assertSame($finder, $finder->exclude('foo'));
148 $this->assertIterator($this->toAbsolute(array('test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
151 public function testIgnoreVCS()
153 $finder = $this->buildFinder();
154 $this->assertSame($finder, $finder->ignoreVCS(false)->ignoreDotFiles(false));
155 $this->assertIterator($this->toAbsolute(array('.git', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'toto/.git', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
157 $finder = $this->buildFinder();
158 $finder->ignoreVCS(false)->ignoreVCS(false)->ignoreDotFiles(false);
159 $this->assertIterator($this->toAbsolute(array('.git', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'toto/.git', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
161 $finder = $this->buildFinder();
162 $this->assertSame($finder, $finder->ignoreVCS(true)->ignoreDotFiles(false));
163 $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
166 public function testIgnoreDotFiles()
168 $finder = $this->buildFinder();
169 $this->assertSame($finder, $finder->ignoreDotFiles(false)->ignoreVCS(false));
170 $this->assertIterator($this->toAbsolute(array('.git', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'toto/.git', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
172 $finder = $this->buildFinder();
173 $finder->ignoreDotFiles(false)->ignoreDotFiles(false)->ignoreVCS(false);
174 $this->assertIterator($this->toAbsolute(array('.git', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'toto/.git', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
176 $finder = $this->buildFinder();
177 $this->assertSame($finder, $finder->ignoreDotFiles(true)->ignoreVCS(false));
178 $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
181 public function testSortByName()
183 $finder = $this->buildFinder();
184 $this->assertSame($finder, $finder->sortByName());
185 $this->assertIterator($this->toAbsolute(array('foo', 'foo bar', 'foo/bar.tmp', 'test.php', 'test.py', 'toto')), $finder->in(self::$tmpDir)->getIterator());
188 public function testSortByType()
190 $finder = $this->buildFinder();
191 $this->assertSame($finder, $finder->sortByType());
192 $this->assertIterator($this->toAbsolute(array('foo', 'foo bar', 'toto', 'foo/bar.tmp', 'test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
195 public function testSortByAccessedTime()
197 $finder = $this->buildFinder();
198 $this->assertSame($finder, $finder->sortByAccessedTime());
199 $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'toto', 'test.py', 'foo', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
202 public function testSortByChangedTime()
204 $finder = $this->buildFinder();
205 $this->assertSame($finder, $finder->sortByChangedTime());
206 $this->assertIterator($this->toAbsolute(array('toto', 'test.py', 'test.php', 'foo/bar.tmp', 'foo', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
209 public function testSortByModifiedTime()
211 $finder = $this->buildFinder();
212 $this->assertSame($finder, $finder->sortByModifiedTime());
213 $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'toto', 'test.py', 'foo', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
216 public function testSort()
218 $finder = $this->buildFinder();
219 $this->assertSame($finder, $finder->sort(function (\SplFileInfo $a, \SplFileInfo $b) { return strcmp($a->getRealPath(), $b->getRealPath()); }));
220 $this->assertIterator($this->toAbsolute(array('foo', 'foo bar', 'foo/bar.tmp', 'test.php', 'test.py', 'toto')), $finder->in(self::$tmpDir)->getIterator());
223 public function testFilter()
225 $finder = $this->buildFinder();
226 $this->assertSame($finder, $finder->filter(function (\SplFileInfo $f) { return false !== strpos($f, 'test'); }));
227 $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
230 public function testFollowLinks()
232 if ('\\' == DIRECTORY_SEPARATOR) {
233 $this->markTestSkipped('symlinks are not supported on Windows');
236 $finder = $this->buildFinder();
237 $this->assertSame($finder, $finder->followLinks());
238 $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
241 public function testIn()
243 $finder = $this->buildFinder();
244 $iterator = $finder->files()->name('*.php')->depth('< 1')->in(array(self::$tmpDir, __DIR__))->getIterator();
247 self::$tmpDir.DIRECTORY_SEPARATOR.'test.php',
248 __DIR__.DIRECTORY_SEPARATOR.'BsdFinderTest.php',
249 __DIR__.DIRECTORY_SEPARATOR.'FinderTest.php',
250 __DIR__.DIRECTORY_SEPARATOR.'GnuFinderTest.php',
251 __DIR__.DIRECTORY_SEPARATOR.'PhpFinderTest.php',
252 __DIR__.DIRECTORY_SEPARATOR.'GlobTest.php',
255 $this->assertIterator($expected, $iterator);
259 * @expectedException \InvalidArgumentException
261 public function testInWithNonExistentDirectory()
263 $finder = new Finder();
264 $finder->in('foobar');
267 public function testInWithGlob()
269 $finder = $this->buildFinder();
270 $finder->in(array(__DIR__.'/Fixtures/*/B/C', __DIR__.'/Fixtures/*/*/B/C'))->getIterator();
272 $this->assertIterator($this->toAbsoluteFixtures(array('A/B/C/abc.dat', 'copy/A/B/C/abc.dat.copy')), $finder);
276 * @expectedException \InvalidArgumentException
278 public function testInWithNonDirectoryGlob()
280 $finder = new Finder();
281 $finder->in(__DIR__.'/Fixtures/A/a*');
284 public function testInWithGlobBrace()
286 $finder = $this->buildFinder();
287 $finder->in(array(__DIR__.'/Fixtures/{A,copy/A}/B/C'))->getIterator();
289 $this->assertIterator($this->toAbsoluteFixtures(array('A/B/C/abc.dat', 'copy/A/B/C/abc.dat.copy')), $finder);
293 * @expectedException \LogicException
295 public function testGetIteratorWithoutIn()
297 $finder = Finder::create();
298 $finder->getIterator();
301 public function testGetIterator()
303 $finder = $this->buildFinder();
305 foreach ($finder->directories()->in(self::$tmpDir) as $dir) {
306 $dirs[] = (string) $dir;
309 $expected = $this->toAbsolute(array('foo', 'toto'));
314 $this->assertEquals($expected, $dirs, 'implements the \IteratorAggregate interface');
316 $finder = $this->buildFinder();
317 $this->assertEquals(2, iterator_count($finder->directories()->in(self::$tmpDir)), 'implements the \IteratorAggregate interface');
319 $finder = $this->buildFinder();
320 $a = iterator_to_array($finder->directories()->in(self::$tmpDir));
321 $a = array_values(array_map('strval', $a));
323 $this->assertEquals($expected, $a, 'implements the \IteratorAggregate interface');
326 public function testRelativePath()
328 $finder = $this->buildFinder()->in(self::$tmpDir);
332 foreach ($finder as $file) {
333 $paths[] = $file->getRelativePath();
336 $ref = array('', '', '', '', 'foo', '');
341 $this->assertEquals($ref, $paths);
344 public function testRelativePathname()
346 $finder = $this->buildFinder()->in(self::$tmpDir)->sortByName();
350 foreach ($finder as $file) {
351 $paths[] = $file->getRelativePathname();
354 $ref = array('test.php', 'toto', 'test.py', 'foo', 'foo'.DIRECTORY_SEPARATOR.'bar.tmp', 'foo bar');
359 $this->assertEquals($ref, $paths);
362 public function testAppendWithAFinder()
364 $finder = $this->buildFinder();
365 $finder->files()->in(self::$tmpDir.DIRECTORY_SEPARATOR.'foo');
367 $finder1 = $this->buildFinder();
368 $finder1->directories()->in(self::$tmpDir);
370 $finder = $finder->append($finder1);
372 $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'toto')), $finder->getIterator());
375 public function testAppendWithAnArray()
377 $finder = $this->buildFinder();
378 $finder->files()->in(self::$tmpDir.DIRECTORY_SEPARATOR.'foo');
380 $finder->append($this->toAbsolute(array('foo', 'toto')));
382 $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'toto')), $finder->getIterator());
385 public function testAppendReturnsAFinder()
387 $this->assertInstanceOf('Symfony\\Component\\Finder\\Finder', Finder::create()->append(array()));
390 public function testAppendDoesNotRequireIn()
392 $finder = $this->buildFinder();
393 $finder->in(self::$tmpDir.DIRECTORY_SEPARATOR.'foo');
395 $finder1 = Finder::create()->append($finder);
397 $this->assertIterator(iterator_to_array($finder->getIterator()), $finder1->getIterator());
400 public function testCountDirectories()
402 $directory = Finder::create()->directories()->in(self::$tmpDir);
405 foreach ($directory as $dir) {
409 $this->assertCount($i, $directory);
412 public function testCountFiles()
414 $files = Finder::create()->files()->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures');
417 foreach ($files as $file) {
421 $this->assertCount($i, $files);
425 * @expectedException \LogicException
427 public function testCountWithoutIn()
429 $finder = Finder::create()->files();
434 * @dataProvider getContainsTestData
436 public function testContains($matchPatterns, $noMatchPatterns, $expected)
438 $finder = $this->buildFinder();
439 $finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures')
440 ->name('*.txt')->sortByName()
441 ->contains($matchPatterns)
442 ->notContains($noMatchPatterns);
444 $this->assertIterator($this->toAbsoluteFixtures($expected), $finder);
447 public function testContainsOnDirectory()
449 $finder = $this->buildFinder();
454 $this->assertIterator(array(), $finder);
457 public function testNotContainsOnDirectory()
459 $finder = $this->buildFinder();
463 ->notContains('abc');
464 $this->assertIterator(array(), $finder);
468 * Searching in multiple locations involves AppendIterator which does an unnecessary rewind which leaves FilterIterator
469 * with inner FilesystemIterator in an invalid state.
471 * @see https://bugs.php.net/68557
473 public function testMultipleLocations()
477 self::$tmpDir.'/toto/',
480 // it is expected that there are test.py test.php in the tmpDir
481 $finder = new Finder();
482 $finder->in($locations)
483 // the default flag IGNORE_DOT_FILES fixes the problem indirectly
484 // so we set it to false for better isolation
485 ->ignoreDotFiles(false)
486 ->depth('< 1')->name('test.php');
488 $this->assertCount(1, $finder);
492 * Searching in multiple locations with sub directories involves
493 * AppendIterator which does an unnecessary rewind which leaves
494 * FilterIterator with inner FilesystemIterator in an invalid state.
496 * @see https://bugs.php.net/68557
498 public function testMultipleLocationsWithSubDirectories()
501 __DIR__.'/Fixtures/one',
502 self::$tmpDir.DIRECTORY_SEPARATOR.'toto',
505 $finder = $this->buildFinder();
506 $finder->in($locations)->depth('< 10')->name('*.neon');
509 __DIR__.'/Fixtures/one'.DIRECTORY_SEPARATOR.'b'.DIRECTORY_SEPARATOR.'c.neon',
510 __DIR__.'/Fixtures/one'.DIRECTORY_SEPARATOR.'b'.DIRECTORY_SEPARATOR.'d.neon',
513 $this->assertIterator($expected, $finder);
514 $this->assertIteratorInForeach($expected, $finder);
518 * Iterator keys must be the file pathname.
520 public function testIteratorKeys()
522 $finder = $this->buildFinder()->in(self::$tmpDir);
523 foreach ($finder as $key => $file) {
524 $this->assertEquals($file->getPathname(), $key);
528 public function testRegexSpecialCharsLocationWithPathRestrictionContainingStartFlag()
530 $finder = $this->buildFinder();
531 $finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'r+e.gex[c]a(r)s')
534 $expected = array('r+e.gex[c]a(r)s'.DIRECTORY_SEPARATOR.'dir', 'r+e.gex[c]a(r)s'.DIRECTORY_SEPARATOR.'dir'.DIRECTORY_SEPARATOR.'bar.dat');
535 $this->assertIterator($this->toAbsoluteFixtures($expected), $finder);
541 public function testAdaptersOrdering()
543 $finder = Finder::create()
545 ->addAdapter(new FakeAdapter\NamedAdapter('a'), 0)
546 ->addAdapter(new FakeAdapter\NamedAdapter('b'), -50)
547 ->addAdapter(new FakeAdapter\NamedAdapter('c'), 50)
548 ->addAdapter(new FakeAdapter\NamedAdapter('d'), -25)
549 ->addAdapter(new FakeAdapter\NamedAdapter('e'), 25);
552 array('c', 'e', 'a', 'd', 'b'),
553 array_map(function (AdapterInterface $adapter) {
554 return $adapter->getName();
555 }, $finder->getAdapters())
562 public function testAdaptersChaining()
564 $iterator = new \ArrayIterator(array());
565 $filenames = $this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto'));
566 foreach ($filenames as $file) {
567 $iterator->append(new \Symfony\Component\Finder\SplFileInfo($file, null, null));
570 $finder = Finder::create()
572 ->addAdapter(new FakeAdapter\UnsupportedAdapter(), 3)
573 ->addAdapter(new FakeAdapter\FailingAdapter(), 2)
574 ->addAdapter(new FakeAdapter\DummyAdapter($iterator), 1);
576 $this->assertIterator($filenames, $finder->in(sys_get_temp_dir())->getIterator());
579 public function getContainsTestData()
582 array('', '', array()),
583 array('foo', 'bar', array()),
584 array('', 'foobar', array('dolor.txt', 'ipsum.txt', 'lorem.txt')),
585 array('lorem ipsum dolor sit amet', 'foobar', array('lorem.txt')),
586 array('sit', 'bar', array('dolor.txt', 'ipsum.txt', 'lorem.txt')),
587 array('dolor sit amet', '@^L@m', array('dolor.txt', 'ipsum.txt')),
588 array('/^lorem ipsum dolor sit amet$/m', 'foobar', array('lorem.txt')),
589 array('lorem', 'foobar', array('lorem.txt')),
590 array('', 'lorem', array('dolor.txt', 'ipsum.txt')),
591 array('ipsum dolor sit amet', '/^IPSUM/m', array('lorem.txt')),
595 public function getRegexNameTestData()
598 array('~.+\\.p.+~i'),
604 * @dataProvider getTestPathData
606 public function testPath($matchPatterns, $noMatchPatterns, array $expected)
608 $finder = $this->buildFinder();
609 $finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures')
610 ->path($matchPatterns)
611 ->notPath($noMatchPatterns);
613 $this->assertIterator($this->toAbsoluteFixtures($expected), $finder);
619 public function testAdapterSelection()
621 // test that by default, PhpAdapter is selected
622 $adapters = Finder::create()->getAdapters();
623 $this->assertTrue($adapters[0] instanceof PhpAdapter);
625 // test another adapter selection
626 $adapters = Finder::create()->setAdapter('gnu_find')->getAdapters();
627 $this->assertTrue($adapters[0] instanceof GnuFindAdapter);
629 // test that useBestAdapter method removes selection
630 $adapters = Finder::create()->useBestAdapter()->getAdapters();
631 $this->assertFalse($adapters[0] instanceof PhpAdapter);
634 public function getTestPathData()
637 array('', '', array()),
638 array('/^A\/B\/C/', '/C$/',
639 array('A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat'),
641 array('/^A\/B/', 'foobar',
643 'A'.DIRECTORY_SEPARATOR.'B',
644 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
645 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat',
646 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
649 array('A/B/C', 'foobar',
651 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
652 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
653 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
654 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat.copy',
657 array('A/B', 'foobar',
660 'A'.DIRECTORY_SEPARATOR.'B',
661 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
662 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B',
663 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
665 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat',
666 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
667 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat.copy',
668 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat.copy',
671 array('/^with space\//', 'foobar',
673 'with space'.DIRECTORY_SEPARATOR.'foo.txt',
679 public function testAccessDeniedException()
681 if ('\\' === DIRECTORY_SEPARATOR) {
682 $this->markTestSkipped('chmod is not supported on Windows');
685 $finder = $this->buildFinder();
686 $finder->files()->in(self::$tmpDir);
688 // make 'foo' directory non-readable
689 $testDir = self::$tmpDir.DIRECTORY_SEPARATOR.'foo';
690 chmod($testDir, 0333);
692 if (false === $couldRead = is_readable($testDir)) {
694 $this->assertIterator($this->toAbsolute(array('foo bar', 'test.php', 'test.py')), $finder->getIterator());
695 $this->fail('Finder should throw an exception when opening a non-readable directory.');
696 } catch (\Exception $e) {
697 $expectedExceptionClass = 'Symfony\\Component\\Finder\\Exception\\AccessDeniedException';
698 if ($e instanceof \PHPUnit_Framework_ExpectationFailedException) {
699 $this->fail(sprintf("Expected exception:\n%s\nGot:\n%s\nWith comparison failure:\n%s", $expectedExceptionClass, 'PHPUnit_Framework_ExpectationFailedException', $e->getComparisonFailure()->getExpectedAsString()));
702 if ($e instanceof \PHPUnit\Framework\ExpectationFailedException) {
703 $this->fail(sprintf("Expected exception:\n%s\nGot:\n%s\nWith comparison failure:\n%s", $expectedExceptionClass, '\PHPUnit\Framework\ExpectationFailedException', $e->getComparisonFailure()->getExpectedAsString()));
706 $this->assertInstanceOf($expectedExceptionClass, $e);
710 // restore original permissions
711 chmod($testDir, 0777);
712 clearstatcache($testDir);
715 $this->markTestSkipped('could read test files while test requires unreadable');
719 public function testIgnoredAccessDeniedException()
721 if ('\\' === DIRECTORY_SEPARATOR) {
722 $this->markTestSkipped('chmod is not supported on Windows');
725 $finder = $this->buildFinder();
726 $finder->files()->ignoreUnreadableDirs()->in(self::$tmpDir);
728 // make 'foo' directory non-readable
729 $testDir = self::$tmpDir.DIRECTORY_SEPARATOR.'foo';
730 chmod($testDir, 0333);
732 if (false === ($couldRead = is_readable($testDir))) {
733 $this->assertIterator($this->toAbsolute(array('foo bar', 'test.php', 'test.py')), $finder->getIterator());
736 // restore original permissions
737 chmod($testDir, 0777);
738 clearstatcache($testDir);
741 $this->markTestSkipped('could read test files while test requires unreadable');
745 protected function buildFinder()
747 return Finder::create();