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\PhpAdapter;
16 use Symfony\Component\Finder\Finder;
18 class FinderTest extends Iterator\RealIteratorTestCase
20 public function testCreate()
22 $this->assertInstanceOf('Symfony\Component\Finder\Finder', Finder::create());
25 public function testDirectories()
27 $finder = $this->buildFinder();
28 $this->assertSame($finder, $finder->directories());
29 $this->assertIterator($this->toAbsolute(array('foo', 'toto')), $finder->in(self::$tmpDir)->getIterator());
31 $finder = $this->buildFinder();
32 $finder->directories();
34 $finder->directories();
35 $this->assertIterator($this->toAbsolute(array('foo', 'toto')), $finder->in(self::$tmpDir)->getIterator());
38 public function testFiles()
40 $finder = $this->buildFinder();
41 $this->assertSame($finder, $finder->files());
42 $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'test.py', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
44 $finder = $this->buildFinder();
46 $finder->directories();
48 $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'test.py', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
51 public function testDepth()
53 $finder = $this->buildFinder();
54 $this->assertSame($finder, $finder->depth('< 1'));
55 $this->assertIterator($this->toAbsolute(array('foo', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
57 $finder = $this->buildFinder();
58 $this->assertSame($finder, $finder->depth('<= 0'));
59 $this->assertIterator($this->toAbsolute(array('foo', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
61 $finder = $this->buildFinder();
62 $this->assertSame($finder, $finder->depth('>= 1'));
63 $this->assertIterator($this->toAbsolute(array('foo/bar.tmp')), $finder->in(self::$tmpDir)->getIterator());
65 $finder = $this->buildFinder();
66 $finder->depth('< 1')->depth('>= 1');
67 $this->assertIterator(array(), $finder->in(self::$tmpDir)->getIterator());
70 public function testName()
72 $finder = $this->buildFinder();
73 $this->assertSame($finder, $finder->name('*.php'));
74 $this->assertIterator($this->toAbsolute(array('test.php')), $finder->in(self::$tmpDir)->getIterator());
76 $finder = $this->buildFinder();
77 $finder->name('test.ph*');
78 $finder->name('test.py');
79 $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
81 $finder = $this->buildFinder();
82 $finder->name('~^test~i');
83 $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
85 $finder = $this->buildFinder();
86 $finder->name('~\\.php$~i');
87 $this->assertIterator($this->toAbsolute(array('test.php')), $finder->in(self::$tmpDir)->getIterator());
89 $finder = $this->buildFinder();
90 $finder->name('test.p{hp,y}');
91 $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
94 public function testNotName()
96 $finder = $this->buildFinder();
97 $this->assertSame($finder, $finder->notName('*.php'));
98 $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
100 $finder = $this->buildFinder();
101 $finder->notName('*.php');
102 $finder->notName('*.py');
103 $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
105 $finder = $this->buildFinder();
106 $finder->name('test.ph*');
107 $finder->name('test.py');
108 $finder->notName('*.php');
109 $finder->notName('*.py');
110 $this->assertIterator(array(), $finder->in(self::$tmpDir)->getIterator());
112 $finder = $this->buildFinder();
113 $finder->name('test.ph*');
114 $finder->name('test.py');
115 $finder->notName('*.p{hp,y}');
116 $this->assertIterator(array(), $finder->in(self::$tmpDir)->getIterator());
120 * @dataProvider getRegexNameTestData
122 public function testRegexName($regex)
124 $finder = $this->buildFinder();
125 $finder->name($regex);
126 $this->assertIterator($this->toAbsolute(array('test.py', 'test.php')), $finder->in(self::$tmpDir)->getIterator());
129 public function testSize()
131 $finder = $this->buildFinder();
132 $this->assertSame($finder, $finder->files()->size('< 1K')->size('> 500'));
133 $this->assertIterator($this->toAbsolute(array('test.php')), $finder->in(self::$tmpDir)->getIterator());
136 public function testDate()
138 $finder = $this->buildFinder();
139 $this->assertSame($finder, $finder->files()->date('until last month'));
140 $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php')), $finder->in(self::$tmpDir)->getIterator());
143 public function testExclude()
145 $finder = $this->buildFinder();
146 $this->assertSame($finder, $finder->exclude('foo'));
147 $this->assertIterator($this->toAbsolute(array('test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
150 public function testIgnoreVCS()
152 $finder = $this->buildFinder();
153 $this->assertSame($finder, $finder->ignoreVCS(false)->ignoreDotFiles(false));
154 $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());
156 $finder = $this->buildFinder();
157 $finder->ignoreVCS(false)->ignoreVCS(false)->ignoreDotFiles(false);
158 $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());
160 $finder = $this->buildFinder();
161 $this->assertSame($finder, $finder->ignoreVCS(true)->ignoreDotFiles(false));
162 $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());
165 public function testIgnoreDotFiles()
167 $finder = $this->buildFinder();
168 $this->assertSame($finder, $finder->ignoreDotFiles(false)->ignoreVCS(false));
169 $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());
171 $finder = $this->buildFinder();
172 $finder->ignoreDotFiles(false)->ignoreDotFiles(false)->ignoreVCS(false);
173 $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());
175 $finder = $this->buildFinder();
176 $this->assertSame($finder, $finder->ignoreDotFiles(true)->ignoreVCS(false));
177 $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
180 public function testSortByName()
182 $finder = $this->buildFinder();
183 $this->assertSame($finder, $finder->sortByName());
184 $this->assertIterator($this->toAbsolute(array('foo', 'foo bar', 'foo/bar.tmp', 'test.php', 'test.py', 'toto')), $finder->in(self::$tmpDir)->getIterator());
187 public function testSortByType()
189 $finder = $this->buildFinder();
190 $this->assertSame($finder, $finder->sortByType());
191 $this->assertIterator($this->toAbsolute(array('foo', 'foo bar', 'toto', 'foo/bar.tmp', 'test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
194 public function testSortByAccessedTime()
196 $finder = $this->buildFinder();
197 $this->assertSame($finder, $finder->sortByAccessedTime());
198 $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'toto', 'test.py', 'foo', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
201 public function testSortByChangedTime()
203 $finder = $this->buildFinder();
204 $this->assertSame($finder, $finder->sortByChangedTime());
205 $this->assertIterator($this->toAbsolute(array('toto', 'test.py', 'test.php', 'foo/bar.tmp', 'foo', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
208 public function testSortByModifiedTime()
210 $finder = $this->buildFinder();
211 $this->assertSame($finder, $finder->sortByModifiedTime());
212 $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'toto', 'test.py', 'foo', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
215 public function testSort()
217 $finder = $this->buildFinder();
218 $this->assertSame($finder, $finder->sort(function (\SplFileInfo $a, \SplFileInfo $b) { return strcmp($a->getRealPath(), $b->getRealPath()); }));
219 $this->assertIterator($this->toAbsolute(array('foo', 'foo bar', 'foo/bar.tmp', 'test.php', 'test.py', 'toto')), $finder->in(self::$tmpDir)->getIterator());
222 public function testFilter()
224 $finder = $this->buildFinder();
225 $this->assertSame($finder, $finder->filter(function (\SplFileInfo $f) { return false !== strpos($f, 'test'); }));
226 $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
229 public function testFollowLinks()
231 if ('\\' == DIRECTORY_SEPARATOR) {
232 $this->markTestSkipped('symlinks are not supported on Windows');
235 $finder = $this->buildFinder();
236 $this->assertSame($finder, $finder->followLinks());
237 $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
240 public function testIn()
242 $finder = $this->buildFinder();
243 $iterator = $finder->files()->name('*.php')->depth('< 1')->in(array(self::$tmpDir, __DIR__))->getIterator();
246 self::$tmpDir.DIRECTORY_SEPARATOR.'test.php',
247 __DIR__.DIRECTORY_SEPARATOR.'BsdFinderTest.php',
248 __DIR__.DIRECTORY_SEPARATOR.'FinderTest.php',
249 __DIR__.DIRECTORY_SEPARATOR.'GnuFinderTest.php',
250 __DIR__.DIRECTORY_SEPARATOR.'PhpFinderTest.php',
251 __DIR__.DIRECTORY_SEPARATOR.'GlobTest.php',
254 $this->assertIterator($expected, $iterator);
258 * @expectedException \InvalidArgumentException
260 public function testInWithNonExistentDirectory()
262 $finder = new Finder();
263 $finder->in('foobar');
266 public function testInWithGlob()
268 $finder = $this->buildFinder();
269 $finder->in(array(__DIR__.'/Fixtures/*/B/C', __DIR__.'/Fixtures/*/*/B/C'))->getIterator();
271 $this->assertIterator($this->toAbsoluteFixtures(array('A/B/C/abc.dat', 'copy/A/B/C/abc.dat.copy')), $finder);
275 * @expectedException \InvalidArgumentException
277 public function testInWithNonDirectoryGlob()
279 $finder = new Finder();
280 $finder->in(__DIR__.'/Fixtures/A/a*');
283 public function testInWithGlobBrace()
285 $finder = $this->buildFinder();
286 $finder->in(array(__DIR__.'/Fixtures/{A,copy/A}/B/C'))->getIterator();
288 $this->assertIterator($this->toAbsoluteFixtures(array('A/B/C/abc.dat', 'copy/A/B/C/abc.dat.copy')), $finder);
292 * @expectedException \LogicException
294 public function testGetIteratorWithoutIn()
296 $finder = Finder::create();
297 $finder->getIterator();
300 public function testGetIterator()
302 $finder = $this->buildFinder();
304 foreach ($finder->directories()->in(self::$tmpDir) as $dir) {
305 $dirs[] = (string) $dir;
308 $expected = $this->toAbsolute(array('foo', 'toto'));
313 $this->assertEquals($expected, $dirs, 'implements the \IteratorAggregate interface');
315 $finder = $this->buildFinder();
316 $this->assertEquals(2, iterator_count($finder->directories()->in(self::$tmpDir)), 'implements the \IteratorAggregate interface');
318 $finder = $this->buildFinder();
319 $a = iterator_to_array($finder->directories()->in(self::$tmpDir));
320 $a = array_values(array_map('strval', $a));
322 $this->assertEquals($expected, $a, 'implements the \IteratorAggregate interface');
325 public function testRelativePath()
327 $finder = $this->buildFinder()->in(self::$tmpDir);
331 foreach ($finder as $file) {
332 $paths[] = $file->getRelativePath();
335 $ref = array('', '', '', '', 'foo', '');
340 $this->assertEquals($ref, $paths);
343 public function testRelativePathname()
345 $finder = $this->buildFinder()->in(self::$tmpDir)->sortByName();
349 foreach ($finder as $file) {
350 $paths[] = $file->getRelativePathname();
353 $ref = array('test.php', 'toto', 'test.py', 'foo', 'foo'.DIRECTORY_SEPARATOR.'bar.tmp', 'foo bar');
358 $this->assertEquals($ref, $paths);
361 public function testAppendWithAFinder()
363 $finder = $this->buildFinder();
364 $finder->files()->in(self::$tmpDir.DIRECTORY_SEPARATOR.'foo');
366 $finder1 = $this->buildFinder();
367 $finder1->directories()->in(self::$tmpDir);
369 $finder = $finder->append($finder1);
371 $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'toto')), $finder->getIterator());
374 public function testAppendWithAnArray()
376 $finder = $this->buildFinder();
377 $finder->files()->in(self::$tmpDir.DIRECTORY_SEPARATOR.'foo');
379 $finder->append($this->toAbsolute(array('foo', 'toto')));
381 $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'toto')), $finder->getIterator());
384 public function testAppendReturnsAFinder()
386 $this->assertInstanceOf('Symfony\\Component\\Finder\\Finder', Finder::create()->append(array()));
389 public function testAppendDoesNotRequireIn()
391 $finder = $this->buildFinder();
392 $finder->in(self::$tmpDir.DIRECTORY_SEPARATOR.'foo');
394 $finder1 = Finder::create()->append($finder);
396 $this->assertIterator(iterator_to_array($finder->getIterator()), $finder1->getIterator());
399 public function testCountDirectories()
401 $directory = Finder::create()->directories()->in(self::$tmpDir);
404 foreach ($directory as $dir) {
408 $this->assertCount($i, $directory);
411 public function testCountFiles()
413 $files = Finder::create()->files()->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures');
416 foreach ($files as $file) {
420 $this->assertCount($i, $files);
424 * @expectedException \LogicException
426 public function testCountWithoutIn()
428 $finder = Finder::create()->files();
433 * @dataProvider getContainsTestData
435 public function testContains($matchPatterns, $noMatchPatterns, $expected)
437 $finder = $this->buildFinder();
438 $finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures')
439 ->name('*.txt')->sortByName()
440 ->contains($matchPatterns)
441 ->notContains($noMatchPatterns);
443 $this->assertIterator($this->toAbsoluteFixtures($expected), $finder);
446 public function testContainsOnDirectory()
448 $finder = $this->buildFinder();
453 $this->assertIterator(array(), $finder);
456 public function testNotContainsOnDirectory()
458 $finder = $this->buildFinder();
462 ->notContains('abc');
463 $this->assertIterator(array(), $finder);
467 * Searching in multiple locations involves AppendIterator which does an unnecessary rewind which leaves FilterIterator
468 * with inner FilesystemIterator in an invalid state.
470 * @see https://bugs.php.net/68557
472 public function testMultipleLocations()
476 self::$tmpDir.'/toto/',
479 // it is expected that there are test.py test.php in the tmpDir
480 $finder = new Finder();
481 $finder->in($locations)
482 // the default flag IGNORE_DOT_FILES fixes the problem indirectly
483 // so we set it to false for better isolation
484 ->ignoreDotFiles(false)
485 ->depth('< 1')->name('test.php');
487 $this->assertCount(1, $finder);
491 * Searching in multiple locations with sub directories involves
492 * AppendIterator which does an unnecessary rewind which leaves
493 * FilterIterator with inner FilesystemIterator in an invalid state.
495 * @see https://bugs.php.net/68557
497 public function testMultipleLocationsWithSubDirectories()
500 __DIR__.'/Fixtures/one',
501 self::$tmpDir.DIRECTORY_SEPARATOR.'toto',
504 $finder = $this->buildFinder();
505 $finder->in($locations)->depth('< 10')->name('*.neon');
508 __DIR__.'/Fixtures/one'.DIRECTORY_SEPARATOR.'b'.DIRECTORY_SEPARATOR.'c.neon',
509 __DIR__.'/Fixtures/one'.DIRECTORY_SEPARATOR.'b'.DIRECTORY_SEPARATOR.'d.neon',
512 $this->assertIterator($expected, $finder);
513 $this->assertIteratorInForeach($expected, $finder);
517 * Iterator keys must be the file pathname.
519 public function testIteratorKeys()
521 $finder = $this->buildFinder()->in(self::$tmpDir);
522 foreach ($finder as $key => $file) {
523 $this->assertEquals($file->getPathname(), $key);
527 public function testRegexSpecialCharsLocationWithPathRestrictionContainingStartFlag()
529 $finder = $this->buildFinder();
530 $finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'r+e.gex[c]a(r)s')
533 $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');
534 $this->assertIterator($this->toAbsoluteFixtures($expected), $finder);
540 public function testAdaptersOrdering()
542 $finder = Finder::create()
544 ->addAdapter(new FakeAdapter\NamedAdapter('a'), 0)
545 ->addAdapter(new FakeAdapter\NamedAdapter('b'), -50)
546 ->addAdapter(new FakeAdapter\NamedAdapter('c'), 50)
547 ->addAdapter(new FakeAdapter\NamedAdapter('d'), -25)
548 ->addAdapter(new FakeAdapter\NamedAdapter('e'), 25);
551 array('c', 'e', 'a', 'd', 'b'),
552 array_map(function (AdapterInterface $adapter) {
553 return $adapter->getName();
554 }, $finder->getAdapters())
561 public function testAdaptersChaining()
563 $iterator = new \ArrayIterator(array());
564 $filenames = $this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto'));
565 foreach ($filenames as $file) {
566 $iterator->append(new \Symfony\Component\Finder\SplFileInfo($file, null, null));
569 $finder = Finder::create()
571 ->addAdapter(new FakeAdapter\UnsupportedAdapter(), 3)
572 ->addAdapter(new FakeAdapter\FailingAdapter(), 2)
573 ->addAdapter(new FakeAdapter\DummyAdapter($iterator), 1);
575 $this->assertIterator($filenames, $finder->in(sys_get_temp_dir())->getIterator());
578 public function getContainsTestData()
581 array('', '', array()),
582 array('foo', 'bar', array()),
583 array('', 'foobar', array('dolor.txt', 'ipsum.txt', 'lorem.txt')),
584 array('lorem ipsum dolor sit amet', 'foobar', array('lorem.txt')),
585 array('sit', 'bar', array('dolor.txt', 'ipsum.txt', 'lorem.txt')),
586 array('dolor sit amet', '@^L@m', array('dolor.txt', 'ipsum.txt')),
587 array('/^lorem ipsum dolor sit amet$/m', 'foobar', array('lorem.txt')),
588 array('lorem', 'foobar', array('lorem.txt')),
589 array('', 'lorem', array('dolor.txt', 'ipsum.txt')),
590 array('ipsum dolor sit amet', '/^IPSUM/m', array('lorem.txt')),
594 public function getRegexNameTestData()
597 array('~.+\\.p.+~i'),
603 * @dataProvider getTestPathData
605 public function testPath($matchPatterns, $noMatchPatterns, array $expected)
607 $finder = $this->buildFinder();
608 $finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures')
609 ->path($matchPatterns)
610 ->notPath($noMatchPatterns);
612 $this->assertIterator($this->toAbsoluteFixtures($expected), $finder);
618 public function testAdapterSelection()
620 // test that by default, PhpAdapter is selected
621 $adapters = Finder::create()->getAdapters();
622 $this->assertInstanceOf('Symfony\Component\Finder\Adapter\PhpAdapter', $adapters[0]);
624 // test another adapter selection
625 $adapters = Finder::create()->setAdapter('gnu_find')->getAdapters();
626 $this->assertInstanceOf('Symfony\Component\Finder\Adapter\GnuFindAdapter', $adapters[0]);
628 // test that useBestAdapter method removes selection
629 $adapters = Finder::create()->useBestAdapter()->getAdapters();
630 $this->assertNotInstanceOf('Symfony\Component\Finder\Adapter\PhpAdapter', $adapters[0]);
633 public function getTestPathData()
636 array('', '', array()),
637 array('/^A\/B\/C/', '/C$/',
638 array('A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat'),
640 array('/^A\/B/', 'foobar',
642 'A'.DIRECTORY_SEPARATOR.'B',
643 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
644 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat',
645 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
648 array('A/B/C', 'foobar',
650 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
651 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
652 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
653 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat.copy',
656 array('A/B', 'foobar',
659 'A'.DIRECTORY_SEPARATOR.'B',
660 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
661 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B',
662 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
664 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat',
665 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
666 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat.copy',
667 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat.copy',
670 array('/^with space\//', 'foobar',
672 'with space'.DIRECTORY_SEPARATOR.'foo.txt',
678 public function testAccessDeniedException()
680 if ('\\' === DIRECTORY_SEPARATOR) {
681 $this->markTestSkipped('chmod is not supported on Windows');
684 $finder = $this->buildFinder();
685 $finder->files()->in(self::$tmpDir);
687 // make 'foo' directory non-readable
688 $testDir = self::$tmpDir.DIRECTORY_SEPARATOR.'foo';
689 chmod($testDir, 0333);
691 if (false === $couldRead = is_readable($testDir)) {
693 $this->assertIterator($this->toAbsolute(array('foo bar', 'test.php', 'test.py')), $finder->getIterator());
694 $this->fail('Finder should throw an exception when opening a non-readable directory.');
695 } catch (\Exception $e) {
696 $expectedExceptionClass = 'Symfony\\Component\\Finder\\Exception\\AccessDeniedException';
697 if ($e instanceof \PHPUnit_Framework_ExpectationFailedException) {
698 $this->fail(sprintf("Expected exception:\n%s\nGot:\n%s\nWith comparison failure:\n%s", $expectedExceptionClass, 'PHPUnit_Framework_ExpectationFailedException', $e->getComparisonFailure()->getExpectedAsString()));
701 if ($e instanceof \PHPUnit\Framework\ExpectationFailedException) {
702 $this->fail(sprintf("Expected exception:\n%s\nGot:\n%s\nWith comparison failure:\n%s", $expectedExceptionClass, '\PHPUnit\Framework\ExpectationFailedException', $e->getComparisonFailure()->getExpectedAsString()));
705 $this->assertInstanceOf($expectedExceptionClass, $e);
709 // restore original permissions
710 chmod($testDir, 0777);
711 clearstatcache($testDir);
714 $this->markTestSkipped('could read test files while test requires unreadable');
718 public function testIgnoredAccessDeniedException()
720 if ('\\' === DIRECTORY_SEPARATOR) {
721 $this->markTestSkipped('chmod is not supported on Windows');
724 $finder = $this->buildFinder();
725 $finder->files()->ignoreUnreadableDirs()->in(self::$tmpDir);
727 // make 'foo' directory non-readable
728 $testDir = self::$tmpDir.DIRECTORY_SEPARATOR.'foo';
729 chmod($testDir, 0333);
731 if (false === ($couldRead = is_readable($testDir))) {
732 $this->assertIterator($this->toAbsolute(array('foo bar', 'test.php', 'test.py')), $finder->getIterator());
735 // restore original permissions
736 chmod($testDir, 0777);
737 clearstatcache($testDir);
740 $this->markTestSkipped('could read test files while test requires unreadable');
744 protected function buildFinder()
746 return Finder::create();