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