FilesystemTest.php (32696B)
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\Filesystem\Tests; 13 14 /** 15 * Test class for Filesystem. 16 */ 17 class FilesystemTest extends FilesystemTestCase 18 { 19 public function testCopyCreatesNewFile() 20 { 21 $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file'; 22 $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file'; 23 24 file_put_contents($sourceFilePath, 'SOURCE FILE'); 25 26 $this->filesystem->copy($sourceFilePath, $targetFilePath); 27 28 $this->assertFileExists($targetFilePath); 29 $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath)); 30 } 31 32 /** 33 * @expectedException \Symfony\Component\Filesystem\Exception\IOException 34 */ 35 public function testCopyFails() 36 { 37 $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file'; 38 $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file'; 39 40 $this->filesystem->copy($sourceFilePath, $targetFilePath); 41 } 42 43 /** 44 * @expectedException \Symfony\Component\Filesystem\Exception\IOException 45 */ 46 public function testCopyUnreadableFileFails() 47 { 48 // skip test on Windows; PHP can't easily set file as unreadable on Windows 49 if ('\\' === DIRECTORY_SEPARATOR) { 50 $this->markTestSkipped('This test cannot run on Windows.'); 51 } 52 53 $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file'; 54 $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file'; 55 56 file_put_contents($sourceFilePath, 'SOURCE FILE'); 57 58 // make sure target cannot be read 59 $this->filesystem->chmod($sourceFilePath, 0222); 60 61 $this->filesystem->copy($sourceFilePath, $targetFilePath); 62 } 63 64 public function testCopyOverridesExistingFileIfModified() 65 { 66 $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file'; 67 $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file'; 68 69 file_put_contents($sourceFilePath, 'SOURCE FILE'); 70 file_put_contents($targetFilePath, 'TARGET FILE'); 71 touch($targetFilePath, time() - 1000); 72 73 $this->filesystem->copy($sourceFilePath, $targetFilePath); 74 75 $this->assertFileExists($targetFilePath); 76 $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath)); 77 } 78 79 public function testCopyDoesNotOverrideExistingFileByDefault() 80 { 81 $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file'; 82 $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file'; 83 84 file_put_contents($sourceFilePath, 'SOURCE FILE'); 85 file_put_contents($targetFilePath, 'TARGET FILE'); 86 87 // make sure both files have the same modification time 88 $modificationTime = time() - 1000; 89 touch($sourceFilePath, $modificationTime); 90 touch($targetFilePath, $modificationTime); 91 92 $this->filesystem->copy($sourceFilePath, $targetFilePath); 93 94 $this->assertFileExists($targetFilePath); 95 $this->assertEquals('TARGET FILE', file_get_contents($targetFilePath)); 96 } 97 98 public function testCopyOverridesExistingFileIfForced() 99 { 100 $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file'; 101 $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file'; 102 103 file_put_contents($sourceFilePath, 'SOURCE FILE'); 104 file_put_contents($targetFilePath, 'TARGET FILE'); 105 106 // make sure both files have the same modification time 107 $modificationTime = time() - 1000; 108 touch($sourceFilePath, $modificationTime); 109 touch($targetFilePath, $modificationTime); 110 111 $this->filesystem->copy($sourceFilePath, $targetFilePath, true); 112 113 $this->assertFileExists($targetFilePath); 114 $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath)); 115 } 116 117 /** 118 * @expectedException \Symfony\Component\Filesystem\Exception\IOException 119 */ 120 public function testCopyWithOverrideWithReadOnlyTargetFails() 121 { 122 // skip test on Windows; PHP can't easily set file as unwritable on Windows 123 if ('\\' === DIRECTORY_SEPARATOR) { 124 $this->markTestSkipped('This test cannot run on Windows.'); 125 } 126 127 $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file'; 128 $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file'; 129 130 file_put_contents($sourceFilePath, 'SOURCE FILE'); 131 file_put_contents($targetFilePath, 'TARGET FILE'); 132 133 // make sure both files have the same modification time 134 $modificationTime = time() - 1000; 135 touch($sourceFilePath, $modificationTime); 136 touch($targetFilePath, $modificationTime); 137 138 // make sure target is read-only 139 $this->filesystem->chmod($targetFilePath, 0444); 140 141 $this->filesystem->copy($sourceFilePath, $targetFilePath, true); 142 } 143 144 public function testCopyCreatesTargetDirectoryIfItDoesNotExist() 145 { 146 $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file'; 147 $targetFileDirectory = $this->workspace.DIRECTORY_SEPARATOR.'directory'; 148 $targetFilePath = $targetFileDirectory.DIRECTORY_SEPARATOR.'copy_target_file'; 149 150 file_put_contents($sourceFilePath, 'SOURCE FILE'); 151 152 $this->filesystem->copy($sourceFilePath, $targetFilePath); 153 154 $this->assertTrue(is_dir($targetFileDirectory)); 155 $this->assertFileExists($targetFilePath); 156 $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath)); 157 } 158 159 public function testCopyForOriginUrlsAndExistingLocalFileDefaultsToNotCopy() 160 { 161 $sourceFilePath = 'http://symfony.com/images/common/logo/logo_symfony_header.png'; 162 $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file'; 163 164 file_put_contents($targetFilePath, 'TARGET FILE'); 165 166 $this->filesystem->copy($sourceFilePath, $targetFilePath, false); 167 168 $this->assertFileExists($targetFilePath); 169 $this->assertEquals(file_get_contents($sourceFilePath), file_get_contents($targetFilePath)); 170 } 171 172 public function testMkdirCreatesDirectoriesRecursively() 173 { 174 $directory = $this->workspace 175 .DIRECTORY_SEPARATOR.'directory' 176 .DIRECTORY_SEPARATOR.'sub_directory'; 177 178 $this->filesystem->mkdir($directory); 179 180 $this->assertTrue(is_dir($directory)); 181 } 182 183 public function testMkdirCreatesDirectoriesFromArray() 184 { 185 $basePath = $this->workspace.DIRECTORY_SEPARATOR; 186 $directories = array( 187 $basePath.'1', $basePath.'2', $basePath.'3', 188 ); 189 190 $this->filesystem->mkdir($directories); 191 192 $this->assertTrue(is_dir($basePath.'1')); 193 $this->assertTrue(is_dir($basePath.'2')); 194 $this->assertTrue(is_dir($basePath.'3')); 195 } 196 197 public function testMkdirCreatesDirectoriesFromTraversableObject() 198 { 199 $basePath = $this->workspace.DIRECTORY_SEPARATOR; 200 $directories = new \ArrayObject(array( 201 $basePath.'1', $basePath.'2', $basePath.'3', 202 )); 203 204 $this->filesystem->mkdir($directories); 205 206 $this->assertTrue(is_dir($basePath.'1')); 207 $this->assertTrue(is_dir($basePath.'2')); 208 $this->assertTrue(is_dir($basePath.'3')); 209 } 210 211 /** 212 * @expectedException \Symfony\Component\Filesystem\Exception\IOException 213 */ 214 public function testMkdirCreatesDirectoriesFails() 215 { 216 $basePath = $this->workspace.DIRECTORY_SEPARATOR; 217 $dir = $basePath.'2'; 218 219 file_put_contents($dir, ''); 220 221 $this->filesystem->mkdir($dir); 222 } 223 224 public function testTouchCreatesEmptyFile() 225 { 226 $file = $this->workspace.DIRECTORY_SEPARATOR.'1'; 227 228 $this->filesystem->touch($file); 229 230 $this->assertFileExists($file); 231 } 232 233 /** 234 * @expectedException \Symfony\Component\Filesystem\Exception\IOException 235 */ 236 public function testTouchFails() 237 { 238 $file = $this->workspace.DIRECTORY_SEPARATOR.'1'.DIRECTORY_SEPARATOR.'2'; 239 240 $this->filesystem->touch($file); 241 } 242 243 public function testTouchCreatesEmptyFilesFromArray() 244 { 245 $basePath = $this->workspace.DIRECTORY_SEPARATOR; 246 $files = array( 247 $basePath.'1', $basePath.'2', $basePath.'3', 248 ); 249 250 $this->filesystem->touch($files); 251 252 $this->assertFileExists($basePath.'1'); 253 $this->assertFileExists($basePath.'2'); 254 $this->assertFileExists($basePath.'3'); 255 } 256 257 public function testTouchCreatesEmptyFilesFromTraversableObject() 258 { 259 $basePath = $this->workspace.DIRECTORY_SEPARATOR; 260 $files = new \ArrayObject(array( 261 $basePath.'1', $basePath.'2', $basePath.'3', 262 )); 263 264 $this->filesystem->touch($files); 265 266 $this->assertFileExists($basePath.'1'); 267 $this->assertFileExists($basePath.'2'); 268 $this->assertFileExists($basePath.'3'); 269 } 270 271 public function testRemoveCleansFilesAndDirectoriesIteratively() 272 { 273 $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR; 274 275 mkdir($basePath); 276 mkdir($basePath.'dir'); 277 touch($basePath.'file'); 278 279 $this->filesystem->remove($basePath); 280 281 $this->assertTrue(!is_dir($basePath)); 282 } 283 284 public function testRemoveCleansArrayOfFilesAndDirectories() 285 { 286 $basePath = $this->workspace.DIRECTORY_SEPARATOR; 287 288 mkdir($basePath.'dir'); 289 touch($basePath.'file'); 290 291 $files = array( 292 $basePath.'dir', $basePath.'file', 293 ); 294 295 $this->filesystem->remove($files); 296 297 $this->assertTrue(!is_dir($basePath.'dir')); 298 $this->assertTrue(!is_file($basePath.'file')); 299 } 300 301 public function testRemoveCleansTraversableObjectOfFilesAndDirectories() 302 { 303 $basePath = $this->workspace.DIRECTORY_SEPARATOR; 304 305 mkdir($basePath.'dir'); 306 touch($basePath.'file'); 307 308 $files = new \ArrayObject(array( 309 $basePath.'dir', $basePath.'file', 310 )); 311 312 $this->filesystem->remove($files); 313 314 $this->assertTrue(!is_dir($basePath.'dir')); 315 $this->assertTrue(!is_file($basePath.'file')); 316 } 317 318 public function testRemoveIgnoresNonExistingFiles() 319 { 320 $basePath = $this->workspace.DIRECTORY_SEPARATOR; 321 322 mkdir($basePath.'dir'); 323 324 $files = array( 325 $basePath.'dir', $basePath.'file', 326 ); 327 328 $this->filesystem->remove($files); 329 330 $this->assertTrue(!is_dir($basePath.'dir')); 331 } 332 333 public function testRemoveCleansInvalidLinks() 334 { 335 $this->markAsSkippedIfSymlinkIsMissing(); 336 337 $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR; 338 339 mkdir($basePath); 340 mkdir($basePath.'dir'); 341 // create symlink to nonexistent file 342 @symlink($basePath.'file', $basePath.'link'); 343 344 $this->filesystem->remove($basePath); 345 346 $this->assertTrue(!is_dir($basePath)); 347 } 348 349 public function testFilesExists() 350 { 351 $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR; 352 353 mkdir($basePath); 354 touch($basePath.'file1'); 355 mkdir($basePath.'folder'); 356 357 $this->assertTrue($this->filesystem->exists($basePath.'file1')); 358 $this->assertTrue($this->filesystem->exists($basePath.'folder')); 359 } 360 361 public function testFilesExistsTraversableObjectOfFilesAndDirectories() 362 { 363 $basePath = $this->workspace.DIRECTORY_SEPARATOR; 364 365 mkdir($basePath.'dir'); 366 touch($basePath.'file'); 367 368 $files = new \ArrayObject(array( 369 $basePath.'dir', $basePath.'file', 370 )); 371 372 $this->assertTrue($this->filesystem->exists($files)); 373 } 374 375 public function testFilesNotExistsTraversableObjectOfFilesAndDirectories() 376 { 377 $basePath = $this->workspace.DIRECTORY_SEPARATOR; 378 379 mkdir($basePath.'dir'); 380 touch($basePath.'file'); 381 touch($basePath.'file2'); 382 383 $files = new \ArrayObject(array( 384 $basePath.'dir', $basePath.'file', $basePath.'file2', 385 )); 386 387 unlink($basePath.'file'); 388 389 $this->assertFalse($this->filesystem->exists($files)); 390 } 391 392 public function testInvalidFileNotExists() 393 { 394 $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR; 395 396 $this->assertFalse($this->filesystem->exists($basePath.time())); 397 } 398 399 public function testChmodChangesFileMode() 400 { 401 $this->markAsSkippedIfChmodIsMissing(); 402 403 $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir'; 404 mkdir($dir); 405 $file = $dir.DIRECTORY_SEPARATOR.'file'; 406 touch($file); 407 408 $this->filesystem->chmod($file, 0400); 409 $this->filesystem->chmod($dir, 0753); 410 411 $this->assertFilePermissions(753, $dir); 412 $this->assertFilePermissions(400, $file); 413 } 414 415 public function testChmodWrongMod() 416 { 417 $this->markAsSkippedIfChmodIsMissing(); 418 419 $dir = $this->workspace.DIRECTORY_SEPARATOR.'file'; 420 touch($dir); 421 422 $this->filesystem->chmod($dir, 'Wrongmode'); 423 } 424 425 public function testChmodRecursive() 426 { 427 $this->markAsSkippedIfChmodIsMissing(); 428 429 $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir'; 430 mkdir($dir); 431 $file = $dir.DIRECTORY_SEPARATOR.'file'; 432 touch($file); 433 434 $this->filesystem->chmod($file, 0400, 0000, true); 435 $this->filesystem->chmod($dir, 0753, 0000, true); 436 437 $this->assertFilePermissions(753, $dir); 438 $this->assertFilePermissions(753, $file); 439 } 440 441 public function testChmodAppliesUmask() 442 { 443 $this->markAsSkippedIfChmodIsMissing(); 444 445 $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; 446 touch($file); 447 448 $this->filesystem->chmod($file, 0770, 0022); 449 $this->assertFilePermissions(750, $file); 450 } 451 452 public function testChmodChangesModeOfArrayOfFiles() 453 { 454 $this->markAsSkippedIfChmodIsMissing(); 455 456 $directory = $this->workspace.DIRECTORY_SEPARATOR.'directory'; 457 $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; 458 $files = array($directory, $file); 459 460 mkdir($directory); 461 touch($file); 462 463 $this->filesystem->chmod($files, 0753); 464 465 $this->assertFilePermissions(753, $file); 466 $this->assertFilePermissions(753, $directory); 467 } 468 469 public function testChmodChangesModeOfTraversableFileObject() 470 { 471 $this->markAsSkippedIfChmodIsMissing(); 472 473 $directory = $this->workspace.DIRECTORY_SEPARATOR.'directory'; 474 $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; 475 $files = new \ArrayObject(array($directory, $file)); 476 477 mkdir($directory); 478 touch($file); 479 480 $this->filesystem->chmod($files, 0753); 481 482 $this->assertFilePermissions(753, $file); 483 $this->assertFilePermissions(753, $directory); 484 } 485 486 public function testChown() 487 { 488 $this->markAsSkippedIfPosixIsMissing(); 489 490 $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir'; 491 mkdir($dir); 492 493 $this->filesystem->chown($dir, $this->getFileOwner($dir)); 494 } 495 496 public function testChownRecursive() 497 { 498 $this->markAsSkippedIfPosixIsMissing(); 499 500 $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir'; 501 mkdir($dir); 502 $file = $dir.DIRECTORY_SEPARATOR.'file'; 503 touch($file); 504 505 $this->filesystem->chown($dir, $this->getFileOwner($dir), true); 506 } 507 508 public function testChownSymlink() 509 { 510 $this->markAsSkippedIfSymlinkIsMissing(); 511 512 $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; 513 $link = $this->workspace.DIRECTORY_SEPARATOR.'link'; 514 515 touch($file); 516 517 $this->filesystem->symlink($file, $link); 518 519 $this->filesystem->chown($link, $this->getFileOwner($link)); 520 } 521 522 /** 523 * @expectedException \Symfony\Component\Filesystem\Exception\IOException 524 */ 525 public function testChownSymlinkFails() 526 { 527 $this->markAsSkippedIfSymlinkIsMissing(); 528 529 $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; 530 $link = $this->workspace.DIRECTORY_SEPARATOR.'link'; 531 532 touch($file); 533 534 $this->filesystem->symlink($file, $link); 535 536 $this->filesystem->chown($link, 'user'.time().mt_rand(1000, 9999)); 537 } 538 539 /** 540 * @expectedException \Symfony\Component\Filesystem\Exception\IOException 541 */ 542 public function testChownFail() 543 { 544 $this->markAsSkippedIfPosixIsMissing(); 545 546 $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir'; 547 mkdir($dir); 548 549 $this->filesystem->chown($dir, 'user'.time().mt_rand(1000, 9999)); 550 } 551 552 public function testChgrp() 553 { 554 $this->markAsSkippedIfPosixIsMissing(); 555 556 $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir'; 557 mkdir($dir); 558 559 $this->filesystem->chgrp($dir, $this->getFileGroup($dir)); 560 } 561 562 public function testChgrpRecursive() 563 { 564 $this->markAsSkippedIfPosixIsMissing(); 565 566 $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir'; 567 mkdir($dir); 568 $file = $dir.DIRECTORY_SEPARATOR.'file'; 569 touch($file); 570 571 $this->filesystem->chgrp($dir, $this->getFileGroup($dir), true); 572 } 573 574 public function testChgrpSymlink() 575 { 576 $this->markAsSkippedIfSymlinkIsMissing(); 577 578 $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; 579 $link = $this->workspace.DIRECTORY_SEPARATOR.'link'; 580 581 touch($file); 582 583 $this->filesystem->symlink($file, $link); 584 585 $this->filesystem->chgrp($link, $this->getFileGroup($link)); 586 } 587 588 /** 589 * @expectedException \Symfony\Component\Filesystem\Exception\IOException 590 */ 591 public function testChgrpSymlinkFails() 592 { 593 $this->markAsSkippedIfSymlinkIsMissing(); 594 595 $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; 596 $link = $this->workspace.DIRECTORY_SEPARATOR.'link'; 597 598 touch($file); 599 600 $this->filesystem->symlink($file, $link); 601 602 $this->filesystem->chgrp($link, 'user'.time().mt_rand(1000, 9999)); 603 } 604 605 /** 606 * @expectedException \Symfony\Component\Filesystem\Exception\IOException 607 */ 608 public function testChgrpFail() 609 { 610 $this->markAsSkippedIfPosixIsMissing(); 611 612 $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir'; 613 mkdir($dir); 614 615 $this->filesystem->chgrp($dir, 'user'.time().mt_rand(1000, 9999)); 616 } 617 618 public function testRename() 619 { 620 $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; 621 $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file'; 622 touch($file); 623 624 $this->filesystem->rename($file, $newPath); 625 626 $this->assertFileNotExists($file); 627 $this->assertFileExists($newPath); 628 } 629 630 /** 631 * @expectedException \Symfony\Component\Filesystem\Exception\IOException 632 */ 633 public function testRenameThrowsExceptionIfTargetAlreadyExists() 634 { 635 $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; 636 $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file'; 637 638 touch($file); 639 touch($newPath); 640 641 $this->filesystem->rename($file, $newPath); 642 } 643 644 public function testRenameOverwritesTheTargetIfItAlreadyExists() 645 { 646 $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; 647 $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file'; 648 649 touch($file); 650 touch($newPath); 651 652 $this->filesystem->rename($file, $newPath, true); 653 654 $this->assertFileNotExists($file); 655 $this->assertFileExists($newPath); 656 } 657 658 /** 659 * @expectedException \Symfony\Component\Filesystem\Exception\IOException 660 */ 661 public function testRenameThrowsExceptionOnError() 662 { 663 $file = $this->workspace.DIRECTORY_SEPARATOR.uniqid('fs_test_', true); 664 $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file'; 665 666 $this->filesystem->rename($file, $newPath); 667 } 668 669 public function testSymlink() 670 { 671 if ('\\' === DIRECTORY_SEPARATOR) { 672 $this->markTestSkipped('Windows does not support creating "broken" symlinks'); 673 } 674 675 $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; 676 $link = $this->workspace.DIRECTORY_SEPARATOR.'link'; 677 678 // $file does not exists right now: creating "broken" links is a wanted feature 679 $this->filesystem->symlink($file, $link); 680 681 $this->assertTrue(is_link($link)); 682 683 // Create the linked file AFTER creating the link 684 touch($file); 685 686 $this->assertEquals($file, readlink($link)); 687 } 688 689 /** 690 * @depends testSymlink 691 */ 692 public function testRemoveSymlink() 693 { 694 $this->markAsSkippedIfSymlinkIsMissing(); 695 696 $link = $this->workspace.DIRECTORY_SEPARATOR.'link'; 697 698 $this->filesystem->remove($link); 699 700 $this->assertTrue(!is_link($link)); 701 } 702 703 public function testSymlinkIsOverwrittenIfPointsToDifferentTarget() 704 { 705 $this->markAsSkippedIfSymlinkIsMissing(); 706 707 $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; 708 $link = $this->workspace.DIRECTORY_SEPARATOR.'link'; 709 710 touch($file); 711 symlink($this->workspace, $link); 712 713 $this->filesystem->symlink($file, $link); 714 715 $this->assertTrue(is_link($link)); 716 $this->assertEquals($file, readlink($link)); 717 } 718 719 public function testSymlinkIsNotOverwrittenIfAlreadyCreated() 720 { 721 $this->markAsSkippedIfSymlinkIsMissing(); 722 723 $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; 724 $link = $this->workspace.DIRECTORY_SEPARATOR.'link'; 725 726 touch($file); 727 symlink($file, $link); 728 729 $this->filesystem->symlink($file, $link); 730 731 $this->assertTrue(is_link($link)); 732 $this->assertEquals($file, readlink($link)); 733 } 734 735 public function testSymlinkCreatesTargetDirectoryIfItDoesNotExist() 736 { 737 $this->markAsSkippedIfSymlinkIsMissing(); 738 739 $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; 740 $link1 = $this->workspace.DIRECTORY_SEPARATOR.'dir'.DIRECTORY_SEPARATOR.'link'; 741 $link2 = $this->workspace.DIRECTORY_SEPARATOR.'dir'.DIRECTORY_SEPARATOR.'subdir'.DIRECTORY_SEPARATOR.'link'; 742 743 touch($file); 744 745 $this->filesystem->symlink($file, $link1); 746 $this->filesystem->symlink($file, $link2); 747 748 $this->assertTrue(is_link($link1)); 749 $this->assertEquals($file, readlink($link1)); 750 $this->assertTrue(is_link($link2)); 751 $this->assertEquals($file, readlink($link2)); 752 } 753 754 /** 755 * @dataProvider providePathsForMakePathRelative 756 */ 757 public function testMakePathRelative($endPath, $startPath, $expectedPath) 758 { 759 $path = $this->filesystem->makePathRelative($endPath, $startPath); 760 761 $this->assertEquals($expectedPath, $path); 762 } 763 764 /** 765 * @return array 766 */ 767 public function providePathsForMakePathRelative() 768 { 769 $paths = array( 770 array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/src/Symfony/Component', '../'), 771 array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/src/Symfony/Component/', '../'), 772 array('/var/lib/symfony/src/Symfony', '/var/lib/symfony/src/Symfony/Component', '../'), 773 array('/var/lib/symfony/src/Symfony', '/var/lib/symfony/src/Symfony/Component/', '../'), 774 array('var/lib/symfony/', 'var/lib/symfony/src/Symfony/Component', '../../../'), 775 array('/usr/lib/symfony/', '/var/lib/symfony/src/Symfony/Component', '../../../../../../usr/lib/symfony/'), 776 array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/', 'src/Symfony/'), 777 array('/aa/bb', '/aa/bb', './'), 778 array('/aa/bb', '/aa/bb/', './'), 779 array('/aa/bb/', '/aa/bb', './'), 780 array('/aa/bb/', '/aa/bb/', './'), 781 array('/aa/bb/cc', '/aa/bb/cc/dd', '../'), 782 array('/aa/bb/cc', '/aa/bb/cc/dd/', '../'), 783 array('/aa/bb/cc/', '/aa/bb/cc/dd', '../'), 784 array('/aa/bb/cc/', '/aa/bb/cc/dd/', '../'), 785 array('/aa/bb/cc', '/aa', 'bb/cc/'), 786 array('/aa/bb/cc', '/aa/', 'bb/cc/'), 787 array('/aa/bb/cc/', '/aa', 'bb/cc/'), 788 array('/aa/bb/cc/', '/aa/', 'bb/cc/'), 789 array('/a/aab/bb', '/a/aa', '../aab/bb/'), 790 array('/a/aab/bb', '/a/aa/', '../aab/bb/'), 791 array('/a/aab/bb/', '/a/aa', '../aab/bb/'), 792 array('/a/aab/bb/', '/a/aa/', '../aab/bb/'), 793 ); 794 795 if ('\\' === DIRECTORY_SEPARATOR) { 796 $paths[] = array('c:\var\lib/symfony/src/Symfony/', 'c:/var/lib/symfony/', 'src/Symfony/'); 797 } 798 799 return $paths; 800 } 801 802 public function testMirrorCopiesFilesAndDirectoriesRecursively() 803 { 804 $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR; 805 $directory = $sourcePath.'directory'.DIRECTORY_SEPARATOR; 806 $file1 = $directory.'file1'; 807 $file2 = $sourcePath.'file2'; 808 809 mkdir($sourcePath); 810 mkdir($directory); 811 file_put_contents($file1, 'FILE1'); 812 file_put_contents($file2, 'FILE2'); 813 814 $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR; 815 816 $this->filesystem->mirror($sourcePath, $targetPath); 817 818 $this->assertTrue(is_dir($targetPath)); 819 $this->assertTrue(is_dir($targetPath.'directory')); 820 $this->assertFileEquals($file1, $targetPath.'directory'.DIRECTORY_SEPARATOR.'file1'); 821 $this->assertFileEquals($file2, $targetPath.'file2'); 822 823 $this->filesystem->remove($file1); 824 825 $this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => false)); 826 $this->assertTrue($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1')); 827 828 $this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => true)); 829 $this->assertFalse($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1')); 830 831 file_put_contents($file1, 'FILE1'); 832 833 $this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => true)); 834 $this->assertTrue($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1')); 835 836 $this->filesystem->remove($directory); 837 $this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => true)); 838 $this->assertFalse($this->filesystem->exists($targetPath.'directory')); 839 $this->assertFalse($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1')); 840 } 841 842 public function testMirrorCreatesEmptyDirectory() 843 { 844 $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR; 845 846 mkdir($sourcePath); 847 848 $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR; 849 850 $this->filesystem->mirror($sourcePath, $targetPath); 851 852 $this->assertTrue(is_dir($targetPath)); 853 854 $this->filesystem->remove($sourcePath); 855 } 856 857 public function testMirrorCopiesLinks() 858 { 859 $this->markAsSkippedIfSymlinkIsMissing(); 860 861 $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR; 862 863 mkdir($sourcePath); 864 file_put_contents($sourcePath.'file1', 'FILE1'); 865 symlink($sourcePath.'file1', $sourcePath.'link1'); 866 867 $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR; 868 869 $this->filesystem->mirror($sourcePath, $targetPath); 870 871 $this->assertTrue(is_dir($targetPath)); 872 $this->assertFileEquals($sourcePath.'file1', $targetPath.DIRECTORY_SEPARATOR.'link1'); 873 $this->assertTrue(is_link($targetPath.DIRECTORY_SEPARATOR.'link1')); 874 } 875 876 public function testMirrorCopiesLinkedDirectoryContents() 877 { 878 $this->markAsSkippedIfSymlinkIsMissing(); 879 880 $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR; 881 882 mkdir($sourcePath.'nested/', 0777, true); 883 file_put_contents($sourcePath.'/nested/file1.txt', 'FILE1'); 884 // Note: We symlink directory, not file 885 symlink($sourcePath.'nested', $sourcePath.'link1'); 886 887 $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR; 888 889 $this->filesystem->mirror($sourcePath, $targetPath); 890 891 $this->assertTrue(is_dir($targetPath)); 892 $this->assertFileEquals($sourcePath.'/nested/file1.txt', $targetPath.DIRECTORY_SEPARATOR.'link1/file1.txt'); 893 $this->assertTrue(is_link($targetPath.DIRECTORY_SEPARATOR.'link1')); 894 } 895 896 public function testMirrorCopiesRelativeLinkedContents() 897 { 898 $this->markAsSkippedIfSymlinkIsMissing(); 899 900 $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR; 901 $oldPath = getcwd(); 902 903 mkdir($sourcePath.'nested/', 0777, true); 904 file_put_contents($sourcePath.'/nested/file1.txt', 'FILE1'); 905 // Note: Create relative symlink 906 chdir($sourcePath); 907 symlink('nested', 'link1'); 908 909 chdir($oldPath); 910 911 $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR; 912 913 $this->filesystem->mirror($sourcePath, $targetPath); 914 915 $this->assertTrue(is_dir($targetPath)); 916 $this->assertFileEquals($sourcePath.'/nested/file1.txt', $targetPath.DIRECTORY_SEPARATOR.'link1/file1.txt'); 917 $this->assertTrue(is_link($targetPath.DIRECTORY_SEPARATOR.'link1')); 918 $this->assertEquals($sourcePath.'nested', readlink($targetPath.DIRECTORY_SEPARATOR.'link1')); 919 } 920 921 /** 922 * @dataProvider providePathsForIsAbsolutePath 923 */ 924 public function testIsAbsolutePath($path, $expectedResult) 925 { 926 $result = $this->filesystem->isAbsolutePath($path); 927 928 $this->assertEquals($expectedResult, $result); 929 } 930 931 /** 932 * @return array 933 */ 934 public function providePathsForIsAbsolutePath() 935 { 936 return array( 937 array('/var/lib', true), 938 array('c:\\\\var\\lib', true), 939 array('\\var\\lib', true), 940 array('var/lib', false), 941 array('../var/lib', false), 942 array('', false), 943 array(null, false), 944 ); 945 } 946 947 public function testDumpFile() 948 { 949 $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt'; 950 951 $this->filesystem->dumpFile($filename, 'bar'); 952 953 $this->assertFileExists($filename); 954 $this->assertSame('bar', file_get_contents($filename)); 955 } 956 957 /** 958 * @group legacy 959 */ 960 public function testDumpFileAndSetPermissions() 961 { 962 $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt'; 963 964 $this->filesystem->dumpFile($filename, 'bar', 0753); 965 966 $this->assertFileExists($filename); 967 $this->assertSame('bar', file_get_contents($filename)); 968 969 // skip mode check on Windows 970 if ('\\' !== DIRECTORY_SEPARATOR) { 971 $this->assertFilePermissions(753, $filename); 972 } 973 } 974 975 public function testDumpFileWithNullMode() 976 { 977 $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt'; 978 979 $this->filesystem->dumpFile($filename, 'bar', null); 980 981 $this->assertFileExists($filename); 982 $this->assertSame('bar', file_get_contents($filename)); 983 984 // skip mode check on Windows 985 if ('\\' !== DIRECTORY_SEPARATOR) { 986 $this->assertFilePermissions(600, $filename); 987 } 988 } 989 990 public function testDumpFileOverwritesAnExistingFile() 991 { 992 $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo.txt'; 993 file_put_contents($filename, 'FOO BAR'); 994 995 $this->filesystem->dumpFile($filename, 'bar'); 996 997 $this->assertFileExists($filename); 998 $this->assertSame('bar', file_get_contents($filename)); 999 } 1000 1001 public function testCopyShouldKeepExecutionPermission() 1002 { 1003 $this->markAsSkippedIfChmodIsMissing(); 1004 1005 $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file'; 1006 $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file'; 1007 1008 file_put_contents($sourceFilePath, 'SOURCE FILE'); 1009 chmod($sourceFilePath, 0745); 1010 1011 $this->filesystem->copy($sourceFilePath, $targetFilePath); 1012 1013 $this->assertFilePermissions(767, $targetFilePath); 1014 } 1015 }