PageRenderTime 51ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php

https://github.com/linniksa/symfony
PHP | 880 lines | 595 code | 215 blank | 70 comment | 10 complexity | 1b0a62e635146628be5182889e3a52cb MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Filesystem\Tests;
  11. use Symfony\Component\Filesystem\Filesystem;
  12. /**
  13. * Test class for Filesystem.
  14. */
  15. class FilesystemTest extends \PHPUnit_Framework_TestCase
  16. {
  17. /**
  18. * @var string $workspace
  19. */
  20. private $workspace = null;
  21. /**
  22. * @var \Symfony\Component\Filesystem\Filesystem $filesystem
  23. */
  24. private $filesystem = null;
  25. public function setUp()
  26. {
  27. $this->filesystem = new Filesystem();
  28. $this->workspace = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.time().rand(0, 1000);
  29. mkdir($this->workspace, 0777, true);
  30. }
  31. public function tearDown()
  32. {
  33. $this->clean($this->workspace);
  34. }
  35. /**
  36. * @param string $file
  37. */
  38. private function clean($file)
  39. {
  40. if (is_dir($file) && !is_link($file)) {
  41. $dir = new \FilesystemIterator($file);
  42. foreach ($dir as $childFile) {
  43. $this->clean($childFile);
  44. }
  45. rmdir($file);
  46. } else {
  47. unlink($file);
  48. }
  49. }
  50. public function testCopyCreatesNewFile()
  51. {
  52. $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
  53. $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';
  54. file_put_contents($sourceFilePath, 'SOURCE FILE');
  55. $this->filesystem->copy($sourceFilePath, $targetFilePath);
  56. $this->assertFileExists($targetFilePath);
  57. $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath));
  58. }
  59. /**
  60. * @expectedException Symfony\Component\Filesystem\Exception\IOException
  61. */
  62. public function testCopyFails()
  63. {
  64. $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
  65. $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';
  66. $this->filesystem->copy($sourceFilePath, $targetFilePath);
  67. }
  68. public function testCopyOverridesExistingFileIfModified()
  69. {
  70. $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
  71. $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';
  72. file_put_contents($sourceFilePath, 'SOURCE FILE');
  73. file_put_contents($targetFilePath, 'TARGET FILE');
  74. touch($targetFilePath, time() - 1000);
  75. $this->filesystem->copy($sourceFilePath, $targetFilePath);
  76. $this->assertFileExists($targetFilePath);
  77. $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath));
  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. file_put_contents($sourceFilePath, 'SOURCE FILE');
  84. file_put_contents($targetFilePath, 'TARGET FILE');
  85. // make sure both files have the same modification time
  86. $modificationTime = time() - 1000;
  87. touch($sourceFilePath, $modificationTime);
  88. touch($targetFilePath, $modificationTime);
  89. $this->filesystem->copy($sourceFilePath, $targetFilePath);
  90. $this->assertFileExists($targetFilePath);
  91. $this->assertEquals('TARGET FILE', file_get_contents($targetFilePath));
  92. }
  93. public function testCopyOverridesExistingFileIfForced()
  94. {
  95. $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
  96. $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';
  97. file_put_contents($sourceFilePath, 'SOURCE FILE');
  98. file_put_contents($targetFilePath, 'TARGET FILE');
  99. // make sure both files have the same modification time
  100. $modificationTime = time() - 1000;
  101. touch($sourceFilePath, $modificationTime);
  102. touch($targetFilePath, $modificationTime);
  103. $this->filesystem->copy($sourceFilePath, $targetFilePath, true);
  104. $this->assertFileExists($targetFilePath);
  105. $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath));
  106. }
  107. public function testCopyCreatesTargetDirectoryIfItDoesNotExist()
  108. {
  109. $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
  110. $targetFileDirectory = $this->workspace.DIRECTORY_SEPARATOR.'directory';
  111. $targetFilePath = $targetFileDirectory.DIRECTORY_SEPARATOR.'copy_target_file';
  112. file_put_contents($sourceFilePath, 'SOURCE FILE');
  113. $this->filesystem->copy($sourceFilePath, $targetFilePath);
  114. $this->assertTrue(is_dir($targetFileDirectory));
  115. $this->assertFileExists($targetFilePath);
  116. $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath));
  117. }
  118. public function testMkdirCreatesDirectoriesRecursively()
  119. {
  120. $directory = $this->workspace
  121. .DIRECTORY_SEPARATOR.'directory'
  122. .DIRECTORY_SEPARATOR.'sub_directory';
  123. $this->filesystem->mkdir($directory);
  124. $this->assertTrue(is_dir($directory));
  125. }
  126. public function testMkdirCreatesDirectoriesFromArray()
  127. {
  128. $basePath = $this->workspace.DIRECTORY_SEPARATOR;
  129. $directories = array(
  130. $basePath.'1', $basePath.'2', $basePath.'3'
  131. );
  132. $this->filesystem->mkdir($directories);
  133. $this->assertTrue(is_dir($basePath.'1'));
  134. $this->assertTrue(is_dir($basePath.'2'));
  135. $this->assertTrue(is_dir($basePath.'3'));
  136. }
  137. public function testMkdirCreatesDirectoriesFromTraversableObject()
  138. {
  139. $basePath = $this->workspace.DIRECTORY_SEPARATOR;
  140. $directories = new \ArrayObject(array(
  141. $basePath.'1', $basePath.'2', $basePath.'3'
  142. ));
  143. $this->filesystem->mkdir($directories);
  144. $this->assertTrue(is_dir($basePath.'1'));
  145. $this->assertTrue(is_dir($basePath.'2'));
  146. $this->assertTrue(is_dir($basePath.'3'));
  147. }
  148. /**
  149. * @expectedException Symfony\Component\Filesystem\Exception\IOException
  150. */
  151. public function testMkdirCreatesDirectoriesFails()
  152. {
  153. $basePath = $this->workspace.DIRECTORY_SEPARATOR;
  154. $dir = $basePath.'2';
  155. file_put_contents($dir, '');
  156. $this->filesystem->mkdir($dir);
  157. }
  158. public function testTouchCreatesEmptyFile()
  159. {
  160. $file = $this->workspace.DIRECTORY_SEPARATOR.'1';
  161. $this->filesystem->touch($file);
  162. $this->assertFileExists($file);
  163. }
  164. /**
  165. * @expectedException Symfony\Component\Filesystem\Exception\IOException
  166. */
  167. public function testTouchFails()
  168. {
  169. $file = $this->workspace.DIRECTORY_SEPARATOR.'1'.DIRECTORY_SEPARATOR.'2';
  170. $this->filesystem->touch($file);
  171. }
  172. public function testTouchCreatesEmptyFilesFromArray()
  173. {
  174. $basePath = $this->workspace.DIRECTORY_SEPARATOR;
  175. $files = array(
  176. $basePath.'1', $basePath.'2', $basePath.'3'
  177. );
  178. $this->filesystem->touch($files);
  179. $this->assertFileExists($basePath.'1');
  180. $this->assertFileExists($basePath.'2');
  181. $this->assertFileExists($basePath.'3');
  182. }
  183. public function testTouchCreatesEmptyFilesFromTraversableObject()
  184. {
  185. $basePath = $this->workspace.DIRECTORY_SEPARATOR;
  186. $files = new \ArrayObject(array(
  187. $basePath.'1', $basePath.'2', $basePath.'3'
  188. ));
  189. $this->filesystem->touch($files);
  190. $this->assertFileExists($basePath.'1');
  191. $this->assertFileExists($basePath.'2');
  192. $this->assertFileExists($basePath.'3');
  193. }
  194. public function testRemoveCleansFilesAndDirectoriesIteratively()
  195. {
  196. $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR;
  197. mkdir($basePath);
  198. mkdir($basePath.'dir');
  199. touch($basePath.'file');
  200. $this->filesystem->remove($basePath);
  201. $this->assertTrue(!is_dir($basePath));
  202. }
  203. public function testRemoveCleansArrayOfFilesAndDirectories()
  204. {
  205. $basePath = $this->workspace.DIRECTORY_SEPARATOR;
  206. mkdir($basePath.'dir');
  207. touch($basePath.'file');
  208. $files = array(
  209. $basePath.'dir', $basePath.'file'
  210. );
  211. $this->filesystem->remove($files);
  212. $this->assertTrue(!is_dir($basePath.'dir'));
  213. $this->assertTrue(!is_file($basePath.'file'));
  214. }
  215. public function testRemoveCleansTraversableObjectOfFilesAndDirectories()
  216. {
  217. $basePath = $this->workspace.DIRECTORY_SEPARATOR;
  218. mkdir($basePath.'dir');
  219. touch($basePath.'file');
  220. $files = new \ArrayObject(array(
  221. $basePath.'dir', $basePath.'file'
  222. ));
  223. $this->filesystem->remove($files);
  224. $this->assertTrue(!is_dir($basePath.'dir'));
  225. $this->assertTrue(!is_file($basePath.'file'));
  226. }
  227. public function testRemoveIgnoresNonExistingFiles()
  228. {
  229. $basePath = $this->workspace.DIRECTORY_SEPARATOR;
  230. mkdir($basePath.'dir');
  231. $files = array(
  232. $basePath.'dir', $basePath.'file'
  233. );
  234. $this->filesystem->remove($files);
  235. $this->assertTrue(!is_dir($basePath.'dir'));
  236. }
  237. public function testRemoveCleansInvalidLinks()
  238. {
  239. $this->markAsSkippedIfSymlinkIsMissing();
  240. $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR;
  241. mkdir($basePath);
  242. mkdir($basePath.'dir');
  243. // create symlink to unexisting file
  244. @symlink($basePath.'file', $basePath.'link');
  245. $this->filesystem->remove($basePath);
  246. $this->assertTrue(!is_dir($basePath));
  247. }
  248. public function testFilesExists()
  249. {
  250. $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR;
  251. mkdir($basePath);
  252. touch($basePath.'file1');
  253. mkdir($basePath.'folder');
  254. $this->assertTrue($this->filesystem->exists($basePath.'file1'));
  255. $this->assertTrue($this->filesystem->exists($basePath.'folder'));
  256. }
  257. public function testFilesExistsTraversableObjectOfFilesAndDirectories()
  258. {
  259. $basePath = $this->workspace.DIRECTORY_SEPARATOR;
  260. mkdir($basePath.'dir');
  261. touch($basePath.'file');
  262. $files = new \ArrayObject(array(
  263. $basePath.'dir', $basePath.'file'
  264. ));
  265. $this->assertTrue($this->filesystem->exists($files));
  266. }
  267. public function testFilesNotExistsTraversableObjectOfFilesAndDirectories()
  268. {
  269. $basePath = $this->workspace.DIRECTORY_SEPARATOR;
  270. mkdir($basePath.'dir');
  271. touch($basePath.'file');
  272. touch($basePath.'file2');
  273. $files = new \ArrayObject(array(
  274. $basePath.'dir', $basePath.'file', $basePath.'file2'
  275. ));
  276. unlink($basePath.'file');
  277. $this->assertFalse($this->filesystem->exists($files));
  278. }
  279. public function testInvalidFileNotExists()
  280. {
  281. $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR;
  282. $this->assertFalse($this->filesystem->exists($basePath.time()));
  283. }
  284. public function testChmodChangesFileMode()
  285. {
  286. $this->markAsSkippedIfChmodIsMissing();
  287. $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
  288. mkdir($dir);
  289. $file = $dir.DIRECTORY_SEPARATOR.'file';
  290. touch($file);
  291. $this->filesystem->chmod($file, 0400);
  292. $this->filesystem->chmod($dir, 0753);
  293. $this->assertEquals(753, $this->getFilePermissions($dir));
  294. $this->assertEquals(400, $this->getFilePermissions($file));
  295. }
  296. public function testChmodWrongMod()
  297. {
  298. $this->markAsSkippedIfChmodIsMissing();
  299. $dir = $this->workspace.DIRECTORY_SEPARATOR.'file';
  300. touch($dir);
  301. $this->filesystem->chmod($dir, 'Wrongmode');
  302. }
  303. public function testChmodRecursive()
  304. {
  305. $this->markAsSkippedIfChmodIsMissing();
  306. $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
  307. mkdir($dir);
  308. $file = $dir.DIRECTORY_SEPARATOR.'file';
  309. touch($file);
  310. $this->filesystem->chmod($file, 0400, 0000, true);
  311. $this->filesystem->chmod($dir, 0753, 0000, true);
  312. $this->assertEquals(753, $this->getFilePermissions($dir));
  313. $this->assertEquals(753, $this->getFilePermissions($file));
  314. }
  315. public function testChmodAppliesUmask()
  316. {
  317. $this->markAsSkippedIfChmodIsMissing();
  318. $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
  319. touch($file);
  320. $this->filesystem->chmod($file, 0770, 0022);
  321. $this->assertEquals(750, $this->getFilePermissions($file));
  322. }
  323. public function testChmodChangesModeOfArrayOfFiles()
  324. {
  325. $this->markAsSkippedIfChmodIsMissing();
  326. $directory = $this->workspace.DIRECTORY_SEPARATOR.'directory';
  327. $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
  328. $files = array($directory, $file);
  329. mkdir($directory);
  330. touch($file);
  331. $this->filesystem->chmod($files, 0753);
  332. $this->assertEquals(753, $this->getFilePermissions($file));
  333. $this->assertEquals(753, $this->getFilePermissions($directory));
  334. }
  335. public function testChmodChangesModeOfTraversableFileObject()
  336. {
  337. $this->markAsSkippedIfChmodIsMissing();
  338. $directory = $this->workspace.DIRECTORY_SEPARATOR.'directory';
  339. $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
  340. $files = new \ArrayObject(array($directory, $file));
  341. mkdir($directory);
  342. touch($file);
  343. $this->filesystem->chmod($files, 0753);
  344. $this->assertEquals(753, $this->getFilePermissions($file));
  345. $this->assertEquals(753, $this->getFilePermissions($directory));
  346. }
  347. public function testChown()
  348. {
  349. $this->markAsSkippedIfPosixIsMissing();
  350. $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
  351. mkdir($dir);
  352. $this->filesystem->chown($dir, $this->getFileOwner($dir));
  353. }
  354. public function testChownRecursive()
  355. {
  356. $this->markAsSkippedIfPosixIsMissing();
  357. $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
  358. mkdir($dir);
  359. $file = $dir.DIRECTORY_SEPARATOR.'file';
  360. touch($file);
  361. $this->filesystem->chown($dir, $this->getFileOwner($dir), true);
  362. }
  363. public function testChownSymlink()
  364. {
  365. $this->markAsSkippedIfSymlinkIsMissing();
  366. $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
  367. $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
  368. touch($file);
  369. $this->filesystem->symlink($file, $link);
  370. $this->filesystem->chown($link, $this->getFileOwner($link));
  371. }
  372. /**
  373. * @expectedException Symfony\Component\Filesystem\Exception\IOException
  374. */
  375. public function testChownSymlinkFails()
  376. {
  377. $this->markAsSkippedIfSymlinkIsMissing();
  378. $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
  379. $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
  380. touch($file);
  381. $this->filesystem->symlink($file, $link);
  382. $this->filesystem->chown($link, 'user' . time() . mt_rand(1000, 9999));
  383. }
  384. /**
  385. * @expectedException Symfony\Component\Filesystem\Exception\IOException
  386. */
  387. public function testChownFail()
  388. {
  389. $this->markAsSkippedIfPosixIsMissing();
  390. $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
  391. mkdir($dir);
  392. $this->filesystem->chown($dir, 'user' . time() . mt_rand(1000, 9999));
  393. }
  394. public function testChgrp()
  395. {
  396. $this->markAsSkippedIfPosixIsMissing();
  397. $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
  398. mkdir($dir);
  399. $this->filesystem->chgrp($dir, $this->getFileGroup($dir));
  400. }
  401. public function testChgrpRecursive()
  402. {
  403. $this->markAsSkippedIfPosixIsMissing();
  404. $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
  405. mkdir($dir);
  406. $file = $dir.DIRECTORY_SEPARATOR.'file';
  407. touch($file);
  408. $this->filesystem->chgrp($dir, $this->getFileGroup($dir), true);
  409. }
  410. public function testChgrpSymlink()
  411. {
  412. $this->markAsSkippedIfSymlinkIsMissing();
  413. $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
  414. $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
  415. touch($file);
  416. $this->filesystem->symlink($file, $link);
  417. $this->filesystem->chgrp($link, $this->getFileGroup($link));
  418. }
  419. /**
  420. * @expectedException Symfony\Component\Filesystem\Exception\IOException
  421. */
  422. public function testChgrpSymlinkFails()
  423. {
  424. $this->markAsSkippedIfSymlinkIsMissing();
  425. $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
  426. $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
  427. touch($file);
  428. $this->filesystem->symlink($file, $link);
  429. $this->filesystem->chgrp($link, 'user' . time() . mt_rand(1000, 9999));
  430. }
  431. /**
  432. * @expectedException Symfony\Component\Filesystem\Exception\IOException
  433. */
  434. public function testChgrpFail()
  435. {
  436. $this->markAsSkippedIfPosixIsMissing();
  437. $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
  438. mkdir($dir);
  439. $this->filesystem->chgrp($dir, 'user' . time() . mt_rand(1000, 9999));
  440. }
  441. public function testRename()
  442. {
  443. $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
  444. $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file';
  445. touch($file);
  446. $this->filesystem->rename($file, $newPath);
  447. $this->assertFileNotExists($file);
  448. $this->assertFileExists($newPath);
  449. }
  450. /**
  451. * @expectedException Symfony\Component\Filesystem\Exception\IOException
  452. */
  453. public function testRenameThrowsExceptionIfTargetAlreadyExists()
  454. {
  455. $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
  456. $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file';
  457. touch($file);
  458. touch($newPath);
  459. $this->filesystem->rename($file, $newPath);
  460. }
  461. /**
  462. * @expectedException Symfony\Component\Filesystem\Exception\IOException
  463. */
  464. public function testRenameThrowsExceptionOnError()
  465. {
  466. $file = $this->workspace.DIRECTORY_SEPARATOR.uniqid();
  467. $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file';
  468. $this->filesystem->rename($file, $newPath);
  469. }
  470. public function testSymlink()
  471. {
  472. $this->markAsSkippedIfSymlinkIsMissing();
  473. $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
  474. $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
  475. touch($file);
  476. $this->filesystem->symlink($file, $link);
  477. $this->assertTrue(is_link($link));
  478. $this->assertEquals($file, readlink($link));
  479. }
  480. /**
  481. * @depends testSymlink
  482. */
  483. public function testRemoveSymlink()
  484. {
  485. $this->markAsSkippedIfSymlinkIsMissing();
  486. $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
  487. $this->filesystem->remove($link);
  488. $this->assertTrue(!is_link($link));
  489. }
  490. public function testSymlinkIsOverwrittenIfPointsToDifferentTarget()
  491. {
  492. $this->markAsSkippedIfSymlinkIsMissing();
  493. $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
  494. $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
  495. touch($file);
  496. symlink($this->workspace, $link);
  497. $this->filesystem->symlink($file, $link);
  498. $this->assertTrue(is_link($link));
  499. $this->assertEquals($file, readlink($link));
  500. }
  501. public function testSymlinkIsNotOverwrittenIfAlreadyCreated()
  502. {
  503. $this->markAsSkippedIfSymlinkIsMissing();
  504. $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
  505. $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
  506. touch($file);
  507. symlink($file, $link);
  508. $this->filesystem->symlink($file, $link);
  509. $this->assertTrue(is_link($link));
  510. $this->assertEquals($file, readlink($link));
  511. }
  512. public function testSymlinkCreatesTargetDirectoryIfItDoesNotExist()
  513. {
  514. $this->markAsSkippedIfSymlinkIsMissing();
  515. $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
  516. $link1 = $this->workspace.DIRECTORY_SEPARATOR.'dir'.DIRECTORY_SEPARATOR.'link';
  517. $link2 = $this->workspace.DIRECTORY_SEPARATOR.'dir'.DIRECTORY_SEPARATOR.'subdir'.DIRECTORY_SEPARATOR.'link';
  518. touch($file);
  519. $this->filesystem->symlink($file, $link1);
  520. $this->filesystem->symlink($file, $link2);
  521. $this->assertTrue(is_link($link1));
  522. $this->assertEquals($file, readlink($link1));
  523. $this->assertTrue(is_link($link2));
  524. $this->assertEquals($file, readlink($link2));
  525. }
  526. /**
  527. * @dataProvider providePathsForMakePathRelative
  528. */
  529. public function testMakePathRelative($endPath, $startPath, $expectedPath)
  530. {
  531. $path = $this->filesystem->makePathRelative($endPath, $startPath);
  532. $this->assertEquals($expectedPath, $path);
  533. }
  534. /**
  535. * @return array
  536. */
  537. public function providePathsForMakePathRelative()
  538. {
  539. $paths = array(
  540. array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/src/Symfony/Component', '../'),
  541. array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/src/Symfony/Component/', '../'),
  542. array('/var/lib/symfony/src/Symfony', '/var/lib/symfony/src/Symfony/Component', '../'),
  543. array('/var/lib/symfony/src/Symfony', '/var/lib/symfony/src/Symfony/Component/', '../'),
  544. array('var/lib/symfony/', 'var/lib/symfony/src/Symfony/Component', '../../../'),
  545. array('/usr/lib/symfony/', '/var/lib/symfony/src/Symfony/Component', '../../../../../../usr/lib/symfony/'),
  546. array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/', 'src/Symfony/'),
  547. array('/aa/bb', '/aa/bb', './'),
  548. array('/aa/bb', '/aa/bb/', './'),
  549. array('/aa/bb/', '/aa/bb', './'),
  550. array('/aa/bb/', '/aa/bb/', './'),
  551. array('/aa/bb/cc', '/aa/bb/cc/dd', '../'),
  552. array('/aa/bb/cc', '/aa/bb/cc/dd/', '../'),
  553. array('/aa/bb/cc/', '/aa/bb/cc/dd', '../'),
  554. array('/aa/bb/cc/', '/aa/bb/cc/dd/', '../'),
  555. array('/aa/bb/cc', '/aa', 'bb/cc/'),
  556. array('/aa/bb/cc', '/aa/', 'bb/cc/'),
  557. array('/aa/bb/cc/', '/aa', 'bb/cc/'),
  558. array('/aa/bb/cc/', '/aa/', 'bb/cc/'),
  559. array('/a/aab/bb', '/a/aa', '../aab/bb/'),
  560. array('/a/aab/bb', '/a/aa/', '../aab/bb/'),
  561. array('/a/aab/bb/', '/a/aa', '../aab/bb/'),
  562. array('/a/aab/bb/', '/a/aa/', '../aab/bb/'),
  563. );
  564. if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
  565. $paths[] = array('c:\var\lib/symfony/src/Symfony/', 'c:/var/lib/symfony/', 'src/Symfony/');
  566. }
  567. return $paths;
  568. }
  569. public function testMirrorCopiesFilesAndDirectoriesRecursively()
  570. {
  571. $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR;
  572. $directory = $sourcePath.'directory'.DIRECTORY_SEPARATOR;
  573. $file1 = $directory.'file1';
  574. $file2 = $sourcePath.'file2';
  575. mkdir($sourcePath);
  576. mkdir($directory);
  577. file_put_contents($file1, 'FILE1');
  578. file_put_contents($file2, 'FILE2');
  579. $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR;
  580. $this->filesystem->mirror($sourcePath, $targetPath);
  581. $this->assertTrue(is_dir($targetPath));
  582. $this->assertTrue(is_dir($targetPath.'directory'));
  583. $this->assertFileEquals($file1, $targetPath.'directory'.DIRECTORY_SEPARATOR.'file1');
  584. $this->assertFileEquals($file2, $targetPath.'file2');
  585. }
  586. public function testMirrorCopiesLinks()
  587. {
  588. $this->markAsSkippedIfSymlinkIsMissing();
  589. $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR;
  590. mkdir($sourcePath);
  591. file_put_contents($sourcePath.'file1', 'FILE1');
  592. symlink($sourcePath.'file1', $sourcePath.'link1');
  593. $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR;
  594. $this->filesystem->mirror($sourcePath, $targetPath);
  595. $this->assertTrue(is_dir($targetPath));
  596. $this->assertFileEquals($sourcePath.'file1', $targetPath.DIRECTORY_SEPARATOR.'link1');
  597. $this->assertTrue(is_link($targetPath.DIRECTORY_SEPARATOR.'link1'));
  598. }
  599. /**
  600. * @dataProvider providePathsForIsAbsolutePath
  601. */
  602. public function testIsAbsolutePath($path, $expectedResult)
  603. {
  604. $result = $this->filesystem->isAbsolutePath($path);
  605. $this->assertEquals($expectedResult, $result);
  606. }
  607. /**
  608. * @return array
  609. */
  610. public function providePathsForIsAbsolutePath()
  611. {
  612. return array(
  613. array('/var/lib', true),
  614. array('c:\\\\var\\lib', true),
  615. array('\\var\\lib', true),
  616. array('var/lib', false),
  617. array('../var/lib', false),
  618. array('', false),
  619. array(null, false)
  620. );
  621. }
  622. /**
  623. * Returns file permissions as three digits (i.e. 755)
  624. *
  625. * @return integer
  626. */
  627. private function getFilePermissions($filePath)
  628. {
  629. return (int) substr(sprintf('%o', fileperms($filePath)), -3);
  630. }
  631. private function getFileOwner($filepath)
  632. {
  633. $this->markAsSkippedIfPosixIsMissing();
  634. $infos = stat($filepath);
  635. if ($datas = posix_getpwuid($infos['uid'])) {
  636. return $datas['name'];
  637. }
  638. }
  639. private function getFileGroup($filepath)
  640. {
  641. $this->markAsSkippedIfPosixIsMissing();
  642. $infos = stat($filepath);
  643. if ($datas = posix_getgrgid($infos['gid'])) {
  644. return $datas['name'];
  645. }
  646. }
  647. private function markAsSkippedIfSymlinkIsMissing()
  648. {
  649. if (!function_exists('symlink')) {
  650. $this->markTestSkipped('symlink is not supported');
  651. }
  652. }
  653. private function markAsSkippedIfChmodIsMissing()
  654. {
  655. if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
  656. $this->markTestSkipped('chmod is not supported on windows');
  657. }
  658. }
  659. private function markAsSkippedIfPosixIsMissing()
  660. {
  661. if (defined('PHP_WINDOWS_VERSION_MAJOR') || !function_exists('posix_isatty')) {
  662. $this->markTestSkipped('Posix is not supported');
  663. }
  664. }
  665. }