Yaffs site version 1.1
[yaffs-website] / vendor / symfony / finder / Tests / FinderTest.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Symfony\Component\Finder\Tests;
13
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;
18
19 class FinderTest extends Iterator\RealIteratorTestCase
20 {
21     public function testCreate()
22     {
23         $this->assertInstanceOf('Symfony\Component\Finder\Finder', Finder::create());
24     }
25
26     public function testDirectories()
27     {
28         $finder = $this->buildFinder();
29         $this->assertSame($finder, $finder->directories());
30         $this->assertIterator($this->toAbsolute(array('foo', 'toto')), $finder->in(self::$tmpDir)->getIterator());
31
32         $finder = $this->buildFinder();
33         $finder->directories();
34         $finder->files();
35         $finder->directories();
36         $this->assertIterator($this->toAbsolute(array('foo', 'toto')), $finder->in(self::$tmpDir)->getIterator());
37     }
38
39     public function testFiles()
40     {
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());
44
45         $finder = $this->buildFinder();
46         $finder->files();
47         $finder->directories();
48         $finder->files();
49         $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'test.py', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
50     }
51
52     public function testDepth()
53     {
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());
57
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());
61
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());
65
66         $finder = $this->buildFinder();
67         $finder->depth('< 1')->depth('>= 1');
68         $this->assertIterator(array(), $finder->in(self::$tmpDir)->getIterator());
69     }
70
71     public function testName()
72     {
73         $finder = $this->buildFinder();
74         $this->assertSame($finder, $finder->name('*.php'));
75         $this->assertIterator($this->toAbsolute(array('test.php')), $finder->in(self::$tmpDir)->getIterator());
76
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());
81
82         $finder = $this->buildFinder();
83         $finder->name('~^test~i');
84         $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
85
86         $finder = $this->buildFinder();
87         $finder->name('~\\.php$~i');
88         $this->assertIterator($this->toAbsolute(array('test.php')), $finder->in(self::$tmpDir)->getIterator());
89
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());
93     }
94
95     public function testNotName()
96     {
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());
100
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());
105
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());
112
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());
118     }
119
120     /**
121      * @dataProvider getRegexNameTestData
122      */
123     public function testRegexName($regex)
124     {
125         $finder = $this->buildFinder();
126         $finder->name($regex);
127         $this->assertIterator($this->toAbsolute(array('test.py', 'test.php')), $finder->in(self::$tmpDir)->getIterator());
128     }
129
130     public function testSize()
131     {
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());
135     }
136
137     public function testDate()
138     {
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());
142     }
143
144     public function testExclude()
145     {
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());
149     }
150
151     public function testIgnoreVCS()
152     {
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());
156
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());
160
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());
164     }
165
166     public function testIgnoreDotFiles()
167     {
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());
171
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());
175
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());
179     }
180
181     public function testSortByName()
182     {
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());
186     }
187
188     public function testSortByType()
189     {
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());
193     }
194
195     public function testSortByAccessedTime()
196     {
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());
200     }
201
202     public function testSortByChangedTime()
203     {
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());
207     }
208
209     public function testSortByModifiedTime()
210     {
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());
214     }
215
216     public function testSort()
217     {
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());
221     }
222
223     public function testFilter()
224     {
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());
228     }
229
230     public function testFollowLinks()
231     {
232         if ('\\' == DIRECTORY_SEPARATOR) {
233             $this->markTestSkipped('symlinks are not supported on Windows');
234         }
235
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());
239     }
240
241     public function testIn()
242     {
243         $finder = $this->buildFinder();
244         $iterator = $finder->files()->name('*.php')->depth('< 1')->in(array(self::$tmpDir, __DIR__))->getIterator();
245
246         $expected = array(
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',
253         );
254
255         $this->assertIterator($expected, $iterator);
256     }
257
258     /**
259      * @expectedException \InvalidArgumentException
260      */
261     public function testInWithNonExistentDirectory()
262     {
263         $finder = new Finder();
264         $finder->in('foobar');
265     }
266
267     public function testInWithGlob()
268     {
269         $finder = $this->buildFinder();
270         $finder->in(array(__DIR__.'/Fixtures/*/B/C', __DIR__.'/Fixtures/*/*/B/C'))->getIterator();
271
272         $this->assertIterator($this->toAbsoluteFixtures(array('A/B/C/abc.dat', 'copy/A/B/C/abc.dat.copy')), $finder);
273     }
274
275     /**
276      * @expectedException \InvalidArgumentException
277      */
278     public function testInWithNonDirectoryGlob()
279     {
280         $finder = new Finder();
281         $finder->in(__DIR__.'/Fixtures/A/a*');
282     }
283
284     public function testInWithGlobBrace()
285     {
286         $finder = $this->buildFinder();
287         $finder->in(array(__DIR__.'/Fixtures/{A,copy/A}/B/C'))->getIterator();
288
289         $this->assertIterator($this->toAbsoluteFixtures(array('A/B/C/abc.dat', 'copy/A/B/C/abc.dat.copy')), $finder);
290     }
291
292     /**
293      * @expectedException \LogicException
294      */
295     public function testGetIteratorWithoutIn()
296     {
297         $finder = Finder::create();
298         $finder->getIterator();
299     }
300
301     public function testGetIterator()
302     {
303         $finder = $this->buildFinder();
304         $dirs = array();
305         foreach ($finder->directories()->in(self::$tmpDir) as $dir) {
306             $dirs[] = (string) $dir;
307         }
308
309         $expected = $this->toAbsolute(array('foo', 'toto'));
310
311         sort($dirs);
312         sort($expected);
313
314         $this->assertEquals($expected, $dirs, 'implements the \IteratorAggregate interface');
315
316         $finder = $this->buildFinder();
317         $this->assertEquals(2, iterator_count($finder->directories()->in(self::$tmpDir)), 'implements the \IteratorAggregate interface');
318
319         $finder = $this->buildFinder();
320         $a = iterator_to_array($finder->directories()->in(self::$tmpDir));
321         $a = array_values(array_map('strval', $a));
322         sort($a);
323         $this->assertEquals($expected, $a, 'implements the \IteratorAggregate interface');
324     }
325
326     public function testRelativePath()
327     {
328         $finder = $this->buildFinder()->in(self::$tmpDir);
329
330         $paths = array();
331
332         foreach ($finder as $file) {
333             $paths[] = $file->getRelativePath();
334         }
335
336         $ref = array('', '', '', '', 'foo', '');
337
338         sort($ref);
339         sort($paths);
340
341         $this->assertEquals($ref, $paths);
342     }
343
344     public function testRelativePathname()
345     {
346         $finder = $this->buildFinder()->in(self::$tmpDir)->sortByName();
347
348         $paths = array();
349
350         foreach ($finder as $file) {
351             $paths[] = $file->getRelativePathname();
352         }
353
354         $ref = array('test.php', 'toto', 'test.py', 'foo', 'foo'.DIRECTORY_SEPARATOR.'bar.tmp', 'foo bar');
355
356         sort($paths);
357         sort($ref);
358
359         $this->assertEquals($ref, $paths);
360     }
361
362     public function testAppendWithAFinder()
363     {
364         $finder = $this->buildFinder();
365         $finder->files()->in(self::$tmpDir.DIRECTORY_SEPARATOR.'foo');
366
367         $finder1 = $this->buildFinder();
368         $finder1->directories()->in(self::$tmpDir);
369
370         $finder = $finder->append($finder1);
371
372         $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'toto')), $finder->getIterator());
373     }
374
375     public function testAppendWithAnArray()
376     {
377         $finder = $this->buildFinder();
378         $finder->files()->in(self::$tmpDir.DIRECTORY_SEPARATOR.'foo');
379
380         $finder->append($this->toAbsolute(array('foo', 'toto')));
381
382         $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'toto')), $finder->getIterator());
383     }
384
385     public function testAppendReturnsAFinder()
386     {
387         $this->assertInstanceOf('Symfony\\Component\\Finder\\Finder', Finder::create()->append(array()));
388     }
389
390     public function testAppendDoesNotRequireIn()
391     {
392         $finder = $this->buildFinder();
393         $finder->in(self::$tmpDir.DIRECTORY_SEPARATOR.'foo');
394
395         $finder1 = Finder::create()->append($finder);
396
397         $this->assertIterator(iterator_to_array($finder->getIterator()), $finder1->getIterator());
398     }
399
400     public function testCountDirectories()
401     {
402         $directory = Finder::create()->directories()->in(self::$tmpDir);
403         $i = 0;
404
405         foreach ($directory as $dir) {
406             ++$i;
407         }
408
409         $this->assertCount($i, $directory);
410     }
411
412     public function testCountFiles()
413     {
414         $files = Finder::create()->files()->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures');
415         $i = 0;
416
417         foreach ($files as $file) {
418             ++$i;
419         }
420
421         $this->assertCount($i, $files);
422     }
423
424     /**
425      * @expectedException \LogicException
426      */
427     public function testCountWithoutIn()
428     {
429         $finder = Finder::create()->files();
430         count($finder);
431     }
432
433     /**
434      * @dataProvider getContainsTestData
435      */
436     public function testContains($matchPatterns, $noMatchPatterns, $expected)
437     {
438         $finder = $this->buildFinder();
439         $finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures')
440             ->name('*.txt')->sortByName()
441             ->contains($matchPatterns)
442             ->notContains($noMatchPatterns);
443
444         $this->assertIterator($this->toAbsoluteFixtures($expected), $finder);
445     }
446
447     public function testContainsOnDirectory()
448     {
449         $finder = $this->buildFinder();
450         $finder->in(__DIR__)
451             ->directories()
452             ->name('Fixtures')
453             ->contains('abc');
454         $this->assertIterator(array(), $finder);
455     }
456
457     public function testNotContainsOnDirectory()
458     {
459         $finder = $this->buildFinder();
460         $finder->in(__DIR__)
461             ->directories()
462             ->name('Fixtures')
463             ->notContains('abc');
464         $this->assertIterator(array(), $finder);
465     }
466
467     /**
468      * Searching in multiple locations involves AppendIterator which does an unnecessary rewind which leaves FilterIterator
469      * with inner FilesystemIterator in an invalid state.
470      *
471      * @see https://bugs.php.net/68557
472      */
473     public function testMultipleLocations()
474     {
475         $locations = array(
476             self::$tmpDir.'/',
477             self::$tmpDir.'/toto/',
478         );
479
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');
487
488         $this->assertCount(1, $finder);
489     }
490
491     /**
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.
495      *
496      * @see https://bugs.php.net/68557
497      */
498     public function testMultipleLocationsWithSubDirectories()
499     {
500         $locations = array(
501             __DIR__.'/Fixtures/one',
502             self::$tmpDir.DIRECTORY_SEPARATOR.'toto',
503         );
504
505         $finder = $this->buildFinder();
506         $finder->in($locations)->depth('< 10')->name('*.neon');
507
508         $expected = array(
509             __DIR__.'/Fixtures/one'.DIRECTORY_SEPARATOR.'b'.DIRECTORY_SEPARATOR.'c.neon',
510             __DIR__.'/Fixtures/one'.DIRECTORY_SEPARATOR.'b'.DIRECTORY_SEPARATOR.'d.neon',
511         );
512
513         $this->assertIterator($expected, $finder);
514         $this->assertIteratorInForeach($expected, $finder);
515     }
516
517     /**
518      * Iterator keys must be the file pathname.
519      */
520     public function testIteratorKeys()
521     {
522         $finder = $this->buildFinder()->in(self::$tmpDir);
523         foreach ($finder as $key => $file) {
524             $this->assertEquals($file->getPathname(), $key);
525         }
526     }
527
528     public function testRegexSpecialCharsLocationWithPathRestrictionContainingStartFlag()
529     {
530         $finder = $this->buildFinder();
531         $finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'r+e.gex[c]a(r)s')
532             ->path('/^dir/');
533
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);
536     }
537
538     /**
539      * @group legacy
540      */
541     public function testAdaptersOrdering()
542     {
543         $finder = Finder::create()
544             ->removeAdapters()
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);
550
551         $this->assertEquals(
552             array('c', 'e', 'a', 'd', 'b'),
553             array_map(function (AdapterInterface $adapter) {
554                 return $adapter->getName();
555             }, $finder->getAdapters())
556         );
557     }
558
559     /**
560      * @group legacy
561      */
562     public function testAdaptersChaining()
563     {
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));
568         }
569
570         $finder = Finder::create()
571             ->removeAdapters()
572             ->addAdapter(new FakeAdapter\UnsupportedAdapter(), 3)
573             ->addAdapter(new FakeAdapter\FailingAdapter(), 2)
574             ->addAdapter(new FakeAdapter\DummyAdapter($iterator), 1);
575
576         $this->assertIterator($filenames, $finder->in(sys_get_temp_dir())->getIterator());
577     }
578
579     public function getContainsTestData()
580     {
581         return array(
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')),
592         );
593     }
594
595     public function getRegexNameTestData()
596     {
597         return array(
598             array('~.+\\.p.+~i'),
599             array('~t.*s~i'),
600         );
601     }
602
603     /**
604      * @dataProvider getTestPathData
605      */
606     public function testPath($matchPatterns, $noMatchPatterns, array $expected)
607     {
608         $finder = $this->buildFinder();
609         $finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures')
610             ->path($matchPatterns)
611             ->notPath($noMatchPatterns);
612
613         $this->assertIterator($this->toAbsoluteFixtures($expected), $finder);
614     }
615
616     /**
617      * @group legacy
618      */
619     public function testAdapterSelection()
620     {
621         // test that by default, PhpAdapter is selected
622         $adapters = Finder::create()->getAdapters();
623         $this->assertTrue($adapters[0] instanceof PhpAdapter);
624
625         // test another adapter selection
626         $adapters = Finder::create()->setAdapter('gnu_find')->getAdapters();
627         $this->assertTrue($adapters[0] instanceof GnuFindAdapter);
628
629         // test that useBestAdapter method removes selection
630         $adapters = Finder::create()->useBestAdapter()->getAdapters();
631         $this->assertFalse($adapters[0] instanceof PhpAdapter);
632     }
633
634     public function getTestPathData()
635     {
636         return array(
637             array('', '', array()),
638             array('/^A\/B\/C/', '/C$/',
639                 array('A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat'),
640             ),
641             array('/^A\/B/', 'foobar',
642                 array(
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',
647                 ),
648             ),
649             array('A/B/C', 'foobar',
650                 array(
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',
655                 ),
656             ),
657             array('A/B', 'foobar',
658                 array(
659                     //dirs
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',
664                     //files
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',
669                 ),
670             ),
671             array('/^with space\//', 'foobar',
672                 array(
673                     'with space'.DIRECTORY_SEPARATOR.'foo.txt',
674                 ),
675             ),
676         );
677     }
678
679     public function testAccessDeniedException()
680     {
681         if ('\\' === DIRECTORY_SEPARATOR) {
682             $this->markTestSkipped('chmod is not supported on Windows');
683         }
684
685         $finder = $this->buildFinder();
686         $finder->files()->in(self::$tmpDir);
687
688         // make 'foo' directory non-readable
689         $testDir = self::$tmpDir.DIRECTORY_SEPARATOR.'foo';
690         chmod($testDir, 0333);
691
692         if (false === $couldRead = is_readable($testDir)) {
693             try {
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()));
700                 }
701
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()));
704                 }
705
706                 $this->assertInstanceOf($expectedExceptionClass, $e);
707             }
708         }
709
710         // restore original permissions
711         chmod($testDir, 0777);
712         clearstatcache($testDir);
713
714         if ($couldRead) {
715             $this->markTestSkipped('could read test files while test requires unreadable');
716         }
717     }
718
719     public function testIgnoredAccessDeniedException()
720     {
721         if ('\\' === DIRECTORY_SEPARATOR) {
722             $this->markTestSkipped('chmod is not supported on Windows');
723         }
724
725         $finder = $this->buildFinder();
726         $finder->files()->ignoreUnreadableDirs()->in(self::$tmpDir);
727
728         // make 'foo' directory non-readable
729         $testDir = self::$tmpDir.DIRECTORY_SEPARATOR.'foo';
730         chmod($testDir, 0333);
731
732         if (false === ($couldRead = is_readable($testDir))) {
733             $this->assertIterator($this->toAbsolute(array('foo bar', 'test.php', 'test.py')), $finder->getIterator());
734         }
735
736         // restore original permissions
737         chmod($testDir, 0777);
738         clearstatcache($testDir);
739
740         if ($couldRead) {
741             $this->markTestSkipped('could read test files while test requires unreadable');
742         }
743     }
744
745     protected function buildFinder()
746     {
747         return Finder::create();
748     }
749 }