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\Filesystem\Tests
;
14 use Symfony\Component\Filesystem\Filesystem
;
17 * Test class for Filesystem.
19 class FilesystemTest
extends \PHPUnit_Framework_TestCase
22 * @var string $workspace
24 private $workspace = null;
27 * @var \Symfony\Component\Filesystem\Filesystem $filesystem
29 private $filesystem = null;
31 private static $symlinkOnWindows = null;
33 public static function setUpBeforeClass()
35 if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
36 self
::$symlinkOnWindows = true;
37 $originDir = tempnam(sys_get_temp_dir(), 'sl');
38 $targetDir = tempnam(sys_get_temp_dir(), 'sl');
39 if (true !== @symlink($originDir, $targetDir)) {
40 $report = error_get_last();
41 if (is_array($report) && false !== strpos($report['message'], 'error code(1314)')) {
42 self
::$symlinkOnWindows = false;
48 public function setUp()
50 $this->filesystem
= new Filesystem();
51 $this->workspace
= rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR
).DIRECTORY_SEPARATOR
.time().rand(0, 1000);
52 mkdir($this->workspace
, 0777, true);
53 $this->workspace
= realpath($this->workspace
);
56 public function tearDown()
58 $this->clean($this->workspace
);
64 private function clean($file)
66 if (is_dir($file) && !is_link($file)) {
67 $dir = new \
FilesystemIterator($file);
68 foreach ($dir as $childFile) {
69 $this->clean($childFile);
78 public function testCopyCreatesNewFile()
80 $sourceFilePath = $this->workspace
.DIRECTORY_SEPARATOR
.'copy_source_file';
81 $targetFilePath = $this->workspace
.DIRECTORY_SEPARATOR
.'copy_target_file';
83 file_put_contents($sourceFilePath, 'SOURCE FILE');
85 $this->filesystem
->copy($sourceFilePath, $targetFilePath);
87 $this->assertFileExists($targetFilePath);
88 $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath));
92 * @expectedException \Symfony\Component\Filesystem\Exception\IOException
94 public function testCopyFails()
96 $sourceFilePath = $this->workspace
.DIRECTORY_SEPARATOR
.'copy_source_file';
97 $targetFilePath = $this->workspace
.DIRECTORY_SEPARATOR
.'copy_target_file';
99 $this->filesystem
->copy($sourceFilePath, $targetFilePath);
102 public function testCopyOverridesExistingFileIfModified()
104 $sourceFilePath = $this->workspace
.DIRECTORY_SEPARATOR
.'copy_source_file';
105 $targetFilePath = $this->workspace
.DIRECTORY_SEPARATOR
.'copy_target_file';
107 file_put_contents($sourceFilePath, 'SOURCE FILE');
108 file_put_contents($targetFilePath, 'TARGET FILE');
109 touch($targetFilePath, time() - 1000);
111 $this->filesystem
->copy($sourceFilePath, $targetFilePath);
113 $this->assertFileExists($targetFilePath);
114 $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath));
117 public function testCopyDoesNotOverrideExistingFileByDefault()
119 $sourceFilePath = $this->workspace
.DIRECTORY_SEPARATOR
.'copy_source_file';
120 $targetFilePath = $this->workspace
.DIRECTORY_SEPARATOR
.'copy_target_file';
122 file_put_contents($sourceFilePath, 'SOURCE FILE');
123 file_put_contents($targetFilePath, 'TARGET FILE');
125 // make sure both files have the same modification time
126 $modificationTime = time() - 1000;
127 touch($sourceFilePath, $modificationTime);
128 touch($targetFilePath, $modificationTime);
130 $this->filesystem
->copy($sourceFilePath, $targetFilePath);
132 $this->assertFileExists($targetFilePath);
133 $this->assertEquals('TARGET FILE', file_get_contents($targetFilePath));
136 public function testCopyOverridesExistingFileIfForced()
138 $sourceFilePath = $this->workspace
.DIRECTORY_SEPARATOR
.'copy_source_file';
139 $targetFilePath = $this->workspace
.DIRECTORY_SEPARATOR
.'copy_target_file';
141 file_put_contents($sourceFilePath, 'SOURCE FILE');
142 file_put_contents($targetFilePath, 'TARGET FILE');
144 // make sure both files have the same modification time
145 $modificationTime = time() - 1000;
146 touch($sourceFilePath, $modificationTime);
147 touch($targetFilePath, $modificationTime);
149 $this->filesystem
->copy($sourceFilePath, $targetFilePath, true);
151 $this->assertFileExists($targetFilePath);
152 $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath));
155 public function testCopyCreatesTargetDirectoryIfItDoesNotExist()
157 $sourceFilePath = $this->workspace
.DIRECTORY_SEPARATOR
.'copy_source_file';
158 $targetFileDirectory = $this->workspace
.DIRECTORY_SEPARATOR
.'directory';
159 $targetFilePath = $targetFileDirectory.DIRECTORY_SEPARATOR
.'copy_target_file';
161 file_put_contents($sourceFilePath, 'SOURCE FILE');
163 $this->filesystem
->copy($sourceFilePath, $targetFilePath);
165 $this->assertTrue(is_dir($targetFileDirectory));
166 $this->assertFileExists($targetFilePath);
167 $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath));
170 public function testMkdirCreatesDirectoriesRecursively()
172 $directory = $this->workspace
173 .DIRECTORY_SEPARATOR
.'directory'
174 .DIRECTORY_SEPARATOR
.'sub_directory';
176 $this->filesystem
->mkdir($directory);
178 $this->assertTrue(is_dir($directory));
181 public function testMkdirCreatesDirectoriesFromArray()
183 $basePath = $this->workspace
.DIRECTORY_SEPARATOR
;
184 $directories = array(
185 $basePath.'1', $basePath.'2', $basePath.'3'
188 $this->filesystem
->mkdir($directories);
190 $this->assertTrue(is_dir($basePath.'1'));
191 $this->assertTrue(is_dir($basePath.'2'));
192 $this->assertTrue(is_dir($basePath.'3'));
195 public function testMkdirCreatesDirectoriesFromTraversableObject()
197 $basePath = $this->workspace
.DIRECTORY_SEPARATOR
;
198 $directories = new \
ArrayObject(array(
199 $basePath.'1', $basePath.'2', $basePath.'3'
202 $this->filesystem
->mkdir($directories);
204 $this->assertTrue(is_dir($basePath.'1'));
205 $this->assertTrue(is_dir($basePath.'2'));
206 $this->assertTrue(is_dir($basePath.'3'));
210 * @expectedException \Symfony\Component\Filesystem\Exception\IOException
212 public function testMkdirCreatesDirectoriesFails()
214 $basePath = $this->workspace
.DIRECTORY_SEPARATOR
;
215 $dir = $basePath.'2';
217 file_put_contents($dir, '');
219 $this->filesystem
->mkdir($dir);
222 public function testTouchCreatesEmptyFile()
224 $file = $this->workspace
.DIRECTORY_SEPARATOR
.'1';
226 $this->filesystem
->touch($file);
228 $this->assertFileExists($file);
232 * @expectedException \Symfony\Component\Filesystem\Exception\IOException
234 public function testTouchFails()
236 $file = $this->workspace
.DIRECTORY_SEPARATOR
.'1'.DIRECTORY_SEPARATOR
.'2';
238 $this->filesystem
->touch($file);
241 public function testTouchCreatesEmptyFilesFromArray()
243 $basePath = $this->workspace
.DIRECTORY_SEPARATOR
;
245 $basePath.'1', $basePath.'2', $basePath.'3'
248 $this->filesystem
->touch($files);
250 $this->assertFileExists($basePath.'1');
251 $this->assertFileExists($basePath.'2');
252 $this->assertFileExists($basePath.'3');
255 public function testTouchCreatesEmptyFilesFromTraversableObject()
257 $basePath = $this->workspace
.DIRECTORY_SEPARATOR
;
258 $files = new \
ArrayObject(array(
259 $basePath.'1', $basePath.'2', $basePath.'3'
262 $this->filesystem
->touch($files);
264 $this->assertFileExists($basePath.'1');
265 $this->assertFileExists($basePath.'2');
266 $this->assertFileExists($basePath.'3');
269 public function testRemoveCleansFilesAndDirectoriesIteratively()
271 $basePath = $this->workspace
.DIRECTORY_SEPARATOR
.'directory'.DIRECTORY_SEPARATOR
;
274 mkdir($basePath.'dir');
275 touch($basePath.'file');
277 $this->filesystem
->remove($basePath);
279 $this->assertTrue(!is_dir($basePath));
282 public function testRemoveCleansArrayOfFilesAndDirectories()
284 $basePath = $this->workspace
.DIRECTORY_SEPARATOR
;
286 mkdir($basePath.'dir');
287 touch($basePath.'file');
290 $basePath.'dir', $basePath.'file'
293 $this->filesystem
->remove($files);
295 $this->assertTrue(!is_dir($basePath.'dir'));
296 $this->assertTrue(!is_file($basePath.'file'));
299 public function testRemoveCleansTraversableObjectOfFilesAndDirectories()
301 $basePath = $this->workspace
.DIRECTORY_SEPARATOR
;
303 mkdir($basePath.'dir');
304 touch($basePath.'file');
306 $files = new \
ArrayObject(array(
307 $basePath.'dir', $basePath.'file'
310 $this->filesystem
->remove($files);
312 $this->assertTrue(!is_dir($basePath.'dir'));
313 $this->assertTrue(!is_file($basePath.'file'));
316 public function testRemoveIgnoresNonExistingFiles()
318 $basePath = $this->workspace
.DIRECTORY_SEPARATOR
;
320 mkdir($basePath.'dir');
323 $basePath.'dir', $basePath.'file'
326 $this->filesystem
->remove($files);
328 $this->assertTrue(!is_dir($basePath.'dir'));
331 public function testRemoveCleansInvalidLinks()
333 $this->markAsSkippedIfSymlinkIsMissing();
335 $basePath = $this->workspace
.DIRECTORY_SEPARATOR
.'directory'.DIRECTORY_SEPARATOR
;
338 mkdir($basePath.'dir');
339 // create symlink to unexisting file
340 @symlink($basePath.'file', $basePath.'link');
342 $this->filesystem
->remove($basePath);
344 $this->assertTrue(!is_dir($basePath));
347 public function testFilesExists()
349 $basePath = $this->workspace
.DIRECTORY_SEPARATOR
.'directory'.DIRECTORY_SEPARATOR
;
352 touch($basePath.'file1');
353 mkdir($basePath.'folder');
355 $this->assertTrue($this->filesystem
->exists($basePath.'file1'));
356 $this->assertTrue($this->filesystem
->exists($basePath.'folder'));
359 public function testFilesExistsTraversableObjectOfFilesAndDirectories()
361 $basePath = $this->workspace
.DIRECTORY_SEPARATOR
;
363 mkdir($basePath.'dir');
364 touch($basePath.'file');
366 $files = new \
ArrayObject(array(
367 $basePath.'dir', $basePath.'file'
370 $this->assertTrue($this->filesystem
->exists($files));
373 public function testFilesNotExistsTraversableObjectOfFilesAndDirectories()
375 $basePath = $this->workspace
.DIRECTORY_SEPARATOR
;
377 mkdir($basePath.'dir');
378 touch($basePath.'file');
379 touch($basePath.'file2');
381 $files = new \
ArrayObject(array(
382 $basePath.'dir', $basePath.'file', $basePath.'file2'
385 unlink($basePath.'file');
387 $this->assertFalse($this->filesystem
->exists($files));
390 public function testInvalidFileNotExists()
392 $basePath = $this->workspace
.DIRECTORY_SEPARATOR
.'directory'.DIRECTORY_SEPARATOR
;
394 $this->assertFalse($this->filesystem
->exists($basePath.time()));
397 public function testChmodChangesFileMode()
399 $this->markAsSkippedIfChmodIsMissing();
401 $dir = $this->workspace
.DIRECTORY_SEPARATOR
.'dir';
403 $file = $dir.DIRECTORY_SEPARATOR
.'file';
406 $this->filesystem
->chmod($file, 0400);
407 $this->filesystem
->chmod($dir, 0753);
409 $this->assertEquals(753, $this->getFilePermissions($dir));
410 $this->assertEquals(400, $this->getFilePermissions($file));
413 public function testChmodWrongMod()
415 $this->markAsSkippedIfChmodIsMissing();
417 $dir = $this->workspace
.DIRECTORY_SEPARATOR
.'file';
420 $this->filesystem
->chmod($dir, 'Wrongmode');
423 public function testChmodRecursive()
425 $this->markAsSkippedIfChmodIsMissing();
427 $dir = $this->workspace
.DIRECTORY_SEPARATOR
.'dir';
429 $file = $dir.DIRECTORY_SEPARATOR
.'file';
432 $this->filesystem
->chmod($file, 0400, 0000, true);
433 $this->filesystem
->chmod($dir, 0753, 0000, true);
435 $this->assertEquals(753, $this->getFilePermissions($dir));
436 $this->assertEquals(753, $this->getFilePermissions($file));
439 public function testChmodAppliesUmask()
441 $this->markAsSkippedIfChmodIsMissing();
443 $file = $this->workspace
.DIRECTORY_SEPARATOR
.'file';
446 $this->filesystem
->chmod($file, 0770, 0022);
447 $this->assertEquals(750, $this->getFilePermissions($file));
450 public function testChmodChangesModeOfArrayOfFiles()
452 $this->markAsSkippedIfChmodIsMissing();
454 $directory = $this->workspace
.DIRECTORY_SEPARATOR
.'directory';
455 $file = $this->workspace
.DIRECTORY_SEPARATOR
.'file';
456 $files = array($directory, $file);
461 $this->filesystem
->chmod($files, 0753);
463 $this->assertEquals(753, $this->getFilePermissions($file));
464 $this->assertEquals(753, $this->getFilePermissions($directory));
467 public function testChmodChangesModeOfTraversableFileObject()
469 $this->markAsSkippedIfChmodIsMissing();
471 $directory = $this->workspace
.DIRECTORY_SEPARATOR
.'directory';
472 $file = $this->workspace
.DIRECTORY_SEPARATOR
.'file';
473 $files = new \
ArrayObject(array($directory, $file));
478 $this->filesystem
->chmod($files, 0753);
480 $this->assertEquals(753, $this->getFilePermissions($file));
481 $this->assertEquals(753, $this->getFilePermissions($directory));
484 public function testChown()
486 $this->markAsSkippedIfPosixIsMissing();
488 $dir = $this->workspace
.DIRECTORY_SEPARATOR
.'dir';
491 $this->filesystem
->chown($dir, $this->getFileOwner($dir));
494 public function testChownRecursive()
496 $this->markAsSkippedIfPosixIsMissing();
498 $dir = $this->workspace
.DIRECTORY_SEPARATOR
.'dir';
500 $file = $dir.DIRECTORY_SEPARATOR
.'file';
503 $this->filesystem
->chown($dir, $this->getFileOwner($dir), true);
506 public function testChownSymlink()
508 $this->markAsSkippedIfSymlinkIsMissing();
510 $file = $this->workspace
.DIRECTORY_SEPARATOR
.'file';
511 $link = $this->workspace
.DIRECTORY_SEPARATOR
.'link';
515 $this->filesystem
->symlink($file, $link);
517 $this->filesystem
->chown($link, $this->getFileOwner($link));
521 * @expectedException \Symfony\Component\Filesystem\Exception\IOException
523 public function testChownSymlinkFails()
525 $this->markAsSkippedIfSymlinkIsMissing();
527 $file = $this->workspace
.DIRECTORY_SEPARATOR
.'file';
528 $link = $this->workspace
.DIRECTORY_SEPARATOR
.'link';
532 $this->filesystem
->symlink($file, $link);
534 $this->filesystem
->chown($link, 'user'.time().mt_rand(1000, 9999));
538 * @expectedException \Symfony\Component\Filesystem\Exception\IOException
540 public function testChownFail()
542 $this->markAsSkippedIfPosixIsMissing();
544 $dir = $this->workspace
.DIRECTORY_SEPARATOR
.'dir';
547 $this->filesystem
->chown($dir, 'user'.time().mt_rand(1000, 9999));
550 public function testChgrp()
552 $this->markAsSkippedIfPosixIsMissing();
554 $dir = $this->workspace
.DIRECTORY_SEPARATOR
.'dir';
557 $this->filesystem
->chgrp($dir, $this->getFileGroup($dir));
560 public function testChgrpRecursive()
562 $this->markAsSkippedIfPosixIsMissing();
564 $dir = $this->workspace
.DIRECTORY_SEPARATOR
.'dir';
566 $file = $dir.DIRECTORY_SEPARATOR
.'file';
569 $this->filesystem
->chgrp($dir, $this->getFileGroup($dir), true);
572 public function testChgrpSymlink()
574 $this->markAsSkippedIfSymlinkIsMissing();
576 $file = $this->workspace
.DIRECTORY_SEPARATOR
.'file';
577 $link = $this->workspace
.DIRECTORY_SEPARATOR
.'link';
581 $this->filesystem
->symlink($file, $link);
583 $this->filesystem
->chgrp($link, $this->getFileGroup($link));
587 * @expectedException \Symfony\Component\Filesystem\Exception\IOException
589 public function testChgrpSymlinkFails()
591 $this->markAsSkippedIfSymlinkIsMissing();
593 $file = $this->workspace
.DIRECTORY_SEPARATOR
.'file';
594 $link = $this->workspace
.DIRECTORY_SEPARATOR
.'link';
598 $this->filesystem
->symlink($file, $link);
600 $this->filesystem
->chgrp($link, 'user'.time().mt_rand(1000, 9999));
604 * @expectedException \Symfony\Component\Filesystem\Exception\IOException
606 public function testChgrpFail()
608 $this->markAsSkippedIfPosixIsMissing();
610 $dir = $this->workspace
.DIRECTORY_SEPARATOR
.'dir';
613 $this->filesystem
->chgrp($dir, 'user'.time().mt_rand(1000, 9999));
616 public function testRename()
618 $file = $this->workspace
.DIRECTORY_SEPARATOR
.'file';
619 $newPath = $this->workspace
.DIRECTORY_SEPARATOR
.'new_file';
622 $this->filesystem
->rename($file, $newPath);
624 $this->assertFileNotExists($file);
625 $this->assertFileExists($newPath);
629 * @expectedException \Symfony\Component\Filesystem\Exception\IOException
631 public function testRenameThrowsExceptionIfTargetAlreadyExists()
633 $file = $this->workspace
.DIRECTORY_SEPARATOR
.'file';
634 $newPath = $this->workspace
.DIRECTORY_SEPARATOR
.'new_file';
639 $this->filesystem
->rename($file, $newPath);
642 public function testRenameOverwritesTheTargetIfItAlreadyExists()
644 $file = $this->workspace
.DIRECTORY_SEPARATOR
.'file';
645 $newPath = $this->workspace
.DIRECTORY_SEPARATOR
.'new_file';
650 $this->filesystem
->rename($file, $newPath, true);
652 $this->assertFileNotExists($file);
653 $this->assertFileExists($newPath);
657 * @expectedException \Symfony\Component\Filesystem\Exception\IOException
659 public function testRenameThrowsExceptionOnError()
661 $file = $this->workspace
.DIRECTORY_SEPARATOR
.uniqid();
662 $newPath = $this->workspace
.DIRECTORY_SEPARATOR
.'new_file';
664 $this->filesystem
->rename($file, $newPath);
667 public function testSymlink()
669 $this->markAsSkippedIfSymlinkIsMissing();
671 $file = $this->workspace
.DIRECTORY_SEPARATOR
.'file';
672 $link = $this->workspace
.DIRECTORY_SEPARATOR
.'link';
676 $this->filesystem
->symlink($file, $link);
678 $this->assertTrue(is_link($link));
679 $this->assertEquals($file, readlink($link));
683 * @depends testSymlink
685 public function testRemoveSymlink()
687 $this->markAsSkippedIfSymlinkIsMissing();
689 $link = $this->workspace
.DIRECTORY_SEPARATOR
.'link';
691 $this->filesystem
->remove($link);
693 $this->assertTrue(!is_link($link));
696 public function testSymlinkIsOverwrittenIfPointsToDifferentTarget()
698 $this->markAsSkippedIfSymlinkIsMissing();
700 $file = $this->workspace
.DIRECTORY_SEPARATOR
.'file';
701 $link = $this->workspace
.DIRECTORY_SEPARATOR
.'link';
704 symlink($this->workspace
, $link);
706 $this->filesystem
->symlink($file, $link);
708 $this->assertTrue(is_link($link));
709 $this->assertEquals($file, readlink($link));
712 public function testSymlinkIsNotOverwrittenIfAlreadyCreated()
714 $this->markAsSkippedIfSymlinkIsMissing();
716 $file = $this->workspace
.DIRECTORY_SEPARATOR
.'file';
717 $link = $this->workspace
.DIRECTORY_SEPARATOR
.'link';
720 symlink($file, $link);
722 $this->filesystem
->symlink($file, $link);
724 $this->assertTrue(is_link($link));
725 $this->assertEquals($file, readlink($link));
728 public function testSymlinkCreatesTargetDirectoryIfItDoesNotExist()
730 $this->markAsSkippedIfSymlinkIsMissing();
732 $file = $this->workspace
.DIRECTORY_SEPARATOR
.'file';
733 $link1 = $this->workspace
.DIRECTORY_SEPARATOR
.'dir'.DIRECTORY_SEPARATOR
.'link';
734 $link2 = $this->workspace
.DIRECTORY_SEPARATOR
.'dir'.DIRECTORY_SEPARATOR
.'subdir'.DIRECTORY_SEPARATOR
.'link';
738 $this->filesystem
->symlink($file, $link1);
739 $this->filesystem
->symlink($file, $link2);
741 $this->assertTrue(is_link($link1));
742 $this->assertEquals($file, readlink($link1));
743 $this->assertTrue(is_link($link2));
744 $this->assertEquals($file, readlink($link2));
748 * @dataProvider providePathsForMakePathRelative
750 public function testMakePathRelative($endPath, $startPath, $expectedPath)
752 $path = $this->filesystem
->makePathRelative($endPath, $startPath);
754 $this->assertEquals($expectedPath, $path);
760 public function providePathsForMakePathRelative()
763 array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/src/Symfony/Component', '../'),
764 array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/src/Symfony/Component/', '../'),
765 array('/var/lib/symfony/src/Symfony', '/var/lib/symfony/src/Symfony/Component', '../'),
766 array('/var/lib/symfony/src/Symfony', '/var/lib/symfony/src/Symfony/Component/', '../'),
767 array('var/lib/symfony/', 'var/lib/symfony/src/Symfony/Component', '../../../'),
768 array('/usr/lib/symfony/', '/var/lib/symfony/src/Symfony/Component', '../../../../../../usr/lib/symfony/'),
769 array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/', 'src/Symfony/'),
770 array('/aa/bb', '/aa/bb', './'),
771 array('/aa/bb', '/aa/bb/', './'),
772 array('/aa/bb/', '/aa/bb', './'),
773 array('/aa/bb/', '/aa/bb/', './'),
774 array('/aa/bb/cc', '/aa/bb/cc/dd', '../'),
775 array('/aa/bb/cc', '/aa/bb/cc/dd/', '../'),
776 array('/aa/bb/cc/', '/aa/bb/cc/dd', '../'),
777 array('/aa/bb/cc/', '/aa/bb/cc/dd/', '../'),
778 array('/aa/bb/cc', '/aa', 'bb/cc/'),
779 array('/aa/bb/cc', '/aa/', 'bb/cc/'),
780 array('/aa/bb/cc/', '/aa', 'bb/cc/'),
781 array('/aa/bb/cc/', '/aa/', 'bb/cc/'),
782 array('/a/aab/bb', '/a/aa', '../aab/bb/'),
783 array('/a/aab/bb', '/a/aa/', '../aab/bb/'),
784 array('/a/aab/bb/', '/a/aa', '../aab/bb/'),
785 array('/a/aab/bb/', '/a/aa/', '../aab/bb/'),
788 if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
789 $paths[] = array('c:\var\lib/symfony/src/Symfony/', 'c:/var/lib/symfony/', 'src/Symfony/');
795 public function testMirrorCopiesFilesAndDirectoriesRecursively()
797 $sourcePath = $this->workspace
.DIRECTORY_SEPARATOR
.'source'.DIRECTORY_SEPARATOR
;
798 $directory = $sourcePath.'directory'.DIRECTORY_SEPARATOR
;
799 $file1 = $directory.'file1';
800 $file2 = $sourcePath.'file2';
804 file_put_contents($file1, 'FILE1');
805 file_put_contents($file2, 'FILE2');
807 $targetPath = $this->workspace
.DIRECTORY_SEPARATOR
.'target'.DIRECTORY_SEPARATOR
;
809 $this->filesystem
->mirror($sourcePath, $targetPath);
811 $this->assertTrue(is_dir($targetPath));
812 $this->assertTrue(is_dir($targetPath.'directory'));
813 $this->assertFileEquals($file1, $targetPath.'directory'.DIRECTORY_SEPARATOR
.'file1');
814 $this->assertFileEquals($file2, $targetPath.'file2');
816 $this->filesystem
->remove($file1);
818 $this->filesystem
->mirror($sourcePath, $targetPath, null, array('delete' => false));
819 $this->assertTrue($this->filesystem
->exists($targetPath.'directory'.DIRECTORY_SEPARATOR
.'file1'));
821 $this->filesystem
->mirror($sourcePath, $targetPath, null, array('delete' => true));
822 $this->assertFalse($this->filesystem
->exists($targetPath.'directory'.DIRECTORY_SEPARATOR
.'file1'));
824 file_put_contents($file1, 'FILE1');
826 $this->filesystem
->mirror($sourcePath, $targetPath, null, array('delete' => true));
827 $this->assertTrue($this->filesystem
->exists($targetPath.'directory'.DIRECTORY_SEPARATOR
.'file1'));
829 $this->filesystem
->remove($directory);
830 $this->filesystem
->mirror($sourcePath, $targetPath, null, array('delete' => true));
831 $this->assertFalse($this->filesystem
->exists($targetPath.'directory'));
832 $this->assertFalse($this->filesystem
->exists($targetPath.'directory'.DIRECTORY_SEPARATOR
.'file1'));
835 public function testMirrorCopiesLinks()
837 $this->markAsSkippedIfSymlinkIsMissing();
839 $sourcePath = $this->workspace
.DIRECTORY_SEPARATOR
.'source'.DIRECTORY_SEPARATOR
;
842 file_put_contents($sourcePath.'file1', 'FILE1');
843 symlink($sourcePath.'file1', $sourcePath.'link1');
845 $targetPath = $this->workspace
.DIRECTORY_SEPARATOR
.'target'.DIRECTORY_SEPARATOR
;
847 $this->filesystem
->mirror($sourcePath, $targetPath);
849 $this->assertTrue(is_dir($targetPath));
850 $this->assertFileEquals($sourcePath.'file1', $targetPath.DIRECTORY_SEPARATOR
.'link1');
851 $this->assertTrue(is_link($targetPath.DIRECTORY_SEPARATOR
.'link1'));
854 public function testMirrorCopiesLinkedDirectoryContents()
856 $this->markAsSkippedIfSymlinkIsMissing();
858 $sourcePath = $this->workspace
.DIRECTORY_SEPARATOR
.'source'.DIRECTORY_SEPARATOR
;
860 mkdir($sourcePath.'nested/', 0777, true);
861 file_put_contents($sourcePath.'/nested/file1.txt', 'FILE1');
862 // Note: We symlink directory, not file
863 symlink($sourcePath.'nested', $sourcePath.'link1');
865 $targetPath = $this->workspace
.DIRECTORY_SEPARATOR
.'target'.DIRECTORY_SEPARATOR
;
867 $this->filesystem
->mirror($sourcePath, $targetPath);
869 $this->assertTrue(is_dir($targetPath));
870 $this->assertFileEquals($sourcePath.'/nested/file1.txt', $targetPath.DIRECTORY_SEPARATOR
.'link1/file1.txt');
871 $this->assertTrue(is_link($targetPath.DIRECTORY_SEPARATOR
.'link1'));
875 * @dataProvider providePathsForIsAbsolutePath
877 public function testIsAbsolutePath($path, $expectedResult)
879 $result = $this->filesystem
->isAbsolutePath($path);
881 $this->assertEquals($expectedResult, $result);
887 public function providePathsForIsAbsolutePath()
890 array('/var/lib', true),
891 array('c:\\\\var\\lib', true),
892 array('\\var\\lib', true),
893 array('var/lib', false),
894 array('../var/lib', false),
900 public function testDumpFile()
902 $filename = $this->workspace
.DIRECTORY_SEPARATOR
.'foo'.DIRECTORY_SEPARATOR
.'baz.txt';
904 $this->filesystem
->dumpFile($filename, 'bar', 0753);
906 $this->assertFileExists($filename);
907 $this->assertSame('bar', file_get_contents($filename));
909 // skip mode check on windows
910 if (!defined('PHP_WINDOWS_VERSION_MAJOR')) {
911 $this->assertEquals(753, $this->getFilePermissions($filename));
915 public function testDumpFileOverwritesAnExistingFile()
917 $filename = $this->workspace
.DIRECTORY_SEPARATOR
.'foo.txt';
918 file_put_contents($filename, 'FOO BAR');
920 $this->filesystem
->dumpFile($filename, 'bar');
922 $this->assertFileExists($filename);
923 $this->assertSame('bar', file_get_contents($filename));
927 * Returns file permissions as three digits (i.e. 755)
929 * @param string $filePath
933 private function getFilePermissions($filePath)
935 return (int) substr(sprintf('%o', fileperms($filePath)), -3);
938 private function getFileOwner($filepath)
940 $this->markAsSkippedIfPosixIsMissing();
942 $infos = stat($filepath);
943 if ($datas = posix_getpwuid($infos['uid'])) {
944 return $datas['name'];
948 private function getFileGroup($filepath)
950 $this->markAsSkippedIfPosixIsMissing();
952 $infos = stat($filepath);
953 if ($datas = posix_getgrgid($infos['gid'])) {
954 return $datas['name'];
958 private function markAsSkippedIfSymlinkIsMissing()
960 if (!function_exists('symlink')) {
961 $this->markTestSkipped('symlink is not supported');
964 if (defined('PHP_WINDOWS_VERSION_MAJOR') && false === self
::$symlinkOnWindows) {
965 $this->markTestSkipped('symlink requires "Create symbolic links" privilege on windows');
969 private function markAsSkippedIfChmodIsMissing()
971 if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
972 $this->markTestSkipped('chmod is not supported on windows');
976 private function markAsSkippedIfPosixIsMissing()
978 if (defined('PHP_WINDOWS_VERSION_MAJOR') || !function_exists('posix_isatty')) {
979 $this->markTestSkipped('Posix is not supported');