PageRenderTime 93ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/tests/TestCase/Filesystem/FolderTest.php

https://github.com/ceeram/cakephp
PHP | 1219 lines | 1032 code | 74 blank | 113 comment | 3 complexity | e99835596e26a803f62054314a69fc3b MD5 | raw file
  1. <?php
  2. /**
  3. * FolderTest file
  4. *
  5. * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
  6. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  7. *
  8. * Licensed under The MIT License
  9. * For full copyright and license information, please see the LICENSE.txt
  10. * Redistributions of files must retain the above copyright notice
  11. *
  12. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  13. * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
  14. * @since 1.2.0
  15. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  16. */
  17. namespace Cake\Test\TestCase\Filesystem;
  18. use Cake\Filesystem\File;
  19. use Cake\Filesystem\Folder;
  20. use Cake\TestSuite\TestCase;
  21. /**
  22. * FolderTest class
  23. */
  24. class FolderTest extends TestCase
  25. {
  26. /**
  27. * setUp clearstatcache() to flush file descriptors.
  28. *
  29. * @return void
  30. */
  31. public function setUp()
  32. {
  33. parent::setUp();
  34. clearstatcache();
  35. }
  36. /**
  37. * Remove TMP/tests directory to its original state.
  38. *
  39. * @return void
  40. */
  41. public function tearDown()
  42. {
  43. parent::tearDown();
  44. $cleaner = function ($dir) use (&$cleaner) {
  45. $files = array_diff(scandir($dir), ['.', '..']);
  46. foreach ($files as $file) {
  47. $path = $dir . DS . $file;
  48. if (is_dir($path)) {
  49. $cleaner($path);
  50. } else {
  51. unlink($path);
  52. }
  53. }
  54. rmdir($dir);
  55. };
  56. if (file_exists(TMP . 'tests')) {
  57. $cleaner(TMP . 'tests');
  58. }
  59. parent::tearDown();
  60. }
  61. /**
  62. * testBasic method
  63. *
  64. * @return void
  65. */
  66. public function testBasic()
  67. {
  68. $path = __DIR__;
  69. $Folder = new Folder($path);
  70. $result = $Folder->pwd();
  71. $this->assertEquals($path, $result);
  72. $result = Folder::addPathElement($path, 'test');
  73. $expected = $path . DS . 'test';
  74. $this->assertEquals($expected, $result);
  75. $result = $Folder->cd(ROOT);
  76. $expected = ROOT;
  77. $this->assertEquals($expected, $result);
  78. $result = $Folder->cd(ROOT . DS . 'non-existent');
  79. $this->assertFalse($result);
  80. }
  81. /**
  82. * testInPath method
  83. *
  84. * @return void
  85. */
  86. public function testInPath()
  87. {
  88. $path = dirname(__DIR__);
  89. $inside = dirname($path) . DS;
  90. $Folder = new Folder($path);
  91. $result = $Folder->pwd();
  92. $this->assertEquals($path, $result);
  93. $result = Folder::isSlashTerm($inside);
  94. $this->assertTrue($result);
  95. $result = $Folder->realpath('tests' . DS);
  96. $this->assertEquals($path . DS . 'tests' . DS, $result);
  97. $result = $Folder->inPath('tests' . DS);
  98. $this->assertTrue($result);
  99. $result = $Folder->inPath(DS . 'non-existing' . $inside);
  100. $this->assertFalse($result);
  101. $result = $Folder->inPath($path . DS . 'Model', true);
  102. $this->assertTrue($result);
  103. }
  104. /**
  105. * test creation of single and multiple paths.
  106. *
  107. * @return void
  108. */
  109. public function testCreation()
  110. {
  111. $Folder = new Folder(TMP . 'tests');
  112. $result = $Folder->create(TMP . 'tests' . DS . 'first' . DS . 'second' . DS . 'third');
  113. $this->assertTrue($result);
  114. rmdir(TMP . 'tests' . DS . 'first' . DS . 'second' . DS . 'third');
  115. rmdir(TMP . 'tests' . DS . 'first' . DS . 'second');
  116. rmdir(TMP . 'tests' . DS . 'first');
  117. $Folder = new Folder(TMP . 'tests');
  118. $result = $Folder->create(TMP . 'tests' . DS . 'first');
  119. $this->assertTrue($result);
  120. }
  121. /**
  122. * test that creation of folders with trailing ds works
  123. *
  124. * @return void
  125. */
  126. public function testCreateWithTrailingDs()
  127. {
  128. $Folder = new Folder(TMP . 'tests');
  129. $path = TMP . 'tests' . DS . 'trailing' . DS . 'dir' . DS;
  130. $result = $Folder->create($path);
  131. $this->assertTrue($result);
  132. $this->assertTrue(is_dir($path), 'Folder was not made');
  133. $Folder = new Folder(TMP . 'tests' . DS . 'trailing');
  134. $this->assertTrue($Folder->delete());
  135. }
  136. /**
  137. * Test that relative paths to create() are added to cwd.
  138. *
  139. * @return void
  140. */
  141. public function testCreateRelative()
  142. {
  143. $folder = new Folder(TMP);
  144. $path = TMP . 'tests' . DS . 'relative-test';
  145. $result = $folder->create('tests' . DS . 'relative-test');
  146. $this->assertTrue($result, 'should create');
  147. $this->assertTrue(is_dir($path), 'Folder was not made');
  148. $folder = new Folder($path);
  149. $folder->delete();
  150. }
  151. /**
  152. * test recursive directory create failure.
  153. *
  154. * @return void
  155. */
  156. public function testRecursiveCreateFailure()
  157. {
  158. $this->skipIf(DS === '\\', 'Cant perform operations using permissions on windows.');
  159. $path = TMP . 'tests/one';
  160. mkdir($path, 0777, true);
  161. chmod($path, '0444');
  162. try {
  163. $Folder = new Folder($path);
  164. $result = $Folder->create($path . DS . 'two/three');
  165. $this->assertFalse($result);
  166. } catch (\PHPUnit_Framework_Error $e) {
  167. $this->assertTrue(true);
  168. }
  169. chmod($path, '0777');
  170. rmdir($path);
  171. }
  172. /**
  173. * testOperations method
  174. *
  175. * @return void
  176. */
  177. public function testOperations()
  178. {
  179. $path = CAKE . 'Template';
  180. $Folder = new Folder($path);
  181. $result = $Folder->pwd();
  182. $this->assertSame($path, $result);
  183. $new = TMP . 'tests' . DS . 'test_folder_new';
  184. $result = $Folder->create($new);
  185. $this->assertTrue($result);
  186. $copy = TMP . 'tests' . DS . 'test_folder_copy';
  187. $result = $Folder->copy($copy);
  188. $this->assertTrue($result);
  189. $copy = TMP . 'tests' . DS . 'test_folder_copy';
  190. $result = $Folder->copy($copy);
  191. $this->assertTrue($result);
  192. $copy = TMP . 'tests' . DS . 'test_folder_copy';
  193. $result = $Folder->chmod($copy, 0755, false);
  194. $this->assertTrue($result);
  195. $result = $Folder->cd($copy);
  196. $this->assertTrue((bool)$result);
  197. $mv = TMP . 'tests' . DS . 'test_folder_mv';
  198. $result = $Folder->move($mv);
  199. $this->assertTrue($result);
  200. $mv = TMP . 'tests' . DS . 'test_folder_mv_2';
  201. $result = $Folder->move($mv);
  202. $this->assertTrue($result);
  203. $result = $Folder->delete($new);
  204. $this->assertTrue($result);
  205. $result = $Folder->delete($mv);
  206. $this->assertTrue($result);
  207. $result = $Folder->delete($mv);
  208. $this->assertTrue($result);
  209. $new = CONFIG . 'acl.ini';
  210. $result = $Folder->create($new);
  211. $this->assertFalse($result);
  212. $expected = $new . ' is a file';
  213. $result = $Folder->errors();
  214. $this->assertEquals($expected, $result[0]);
  215. $new = TMP . 'tests' . DS . 'test_folder_new';
  216. $result = $Folder->create($new);
  217. $this->assertTrue($result);
  218. $result = $Folder->cd($new);
  219. $this->assertTrue((bool)$result);
  220. $result = $Folder->delete();
  221. $this->assertTrue($result);
  222. $Folder = new Folder('non-existent');
  223. $result = $Folder->pwd();
  224. $this->assertNull($result);
  225. }
  226. /**
  227. * testChmod method
  228. *
  229. * @return void
  230. */
  231. public function testChmod()
  232. {
  233. $this->skipIf(DS === '\\', 'Folder permissions tests not supported on Windows.');
  234. $path = TMP . 'tests/';
  235. $Folder = new Folder($path);
  236. $subdir = 'test_folder_new';
  237. $new = $path . $subdir;
  238. $this->assertTrue($Folder->create($new));
  239. $this->assertTrue($Folder->create($new . DS . 'test1'));
  240. $this->assertTrue($Folder->create($new . DS . 'test2'));
  241. $filePath = $new . DS . 'test1.php';
  242. $File = new File($filePath);
  243. $this->assertTrue($File->create());
  244. $filePath = $new . DS . 'skip_me.php';
  245. $File = new File($filePath);
  246. $this->assertTrue($File->create());
  247. $this->assertTrue($Folder->chmod($new, 0755, true));
  248. $perms = substr(sprintf('%o', fileperms($new . DS . 'test2')), -4);
  249. $this->assertEquals('0755', $perms);
  250. $this->assertTrue($Folder->chmod($new, 0744, true, ['skip_me.php', 'test2']));
  251. $perms = substr(sprintf('%o', fileperms($new . DS . 'test2')), -4);
  252. $this->assertEquals('0755', $perms);
  253. $perms = substr(sprintf('%o', fileperms($new . DS . 'test1')), -4);
  254. $this->assertEquals('0744', $perms);
  255. }
  256. /**
  257. * testRealPathForWebroot method
  258. *
  259. * @return void
  260. */
  261. public function testRealPathForWebroot()
  262. {
  263. $Folder = new Folder('files' . DS);
  264. $this->assertEquals(realpath('files' . DS), $Folder->path);
  265. }
  266. /**
  267. * testZeroAsDirectory method
  268. *
  269. * @return void
  270. */
  271. public function testZeroAsDirectory()
  272. {
  273. $path = TMP . 'tests';
  274. $Folder = new Folder($path, true);
  275. $new = $path . '/0';
  276. $this->assertTrue($Folder->create($new));
  277. $result = $Folder->read(true, true);
  278. $this->assertContains('0', $result[0]);
  279. $result = $Folder->read(true, ['logs']);
  280. $this->assertContains('0', $result[0]);
  281. $result = $Folder->delete($new);
  282. $this->assertTrue($result);
  283. }
  284. /**
  285. * test Adding path elements to a path
  286. *
  287. * @return void
  288. */
  289. public function testAddPathElement()
  290. {
  291. $expected = DS . 'some' . DS . 'dir' . DS . 'another_path';
  292. $result = Folder::addPathElement(DS . 'some' . DS . 'dir', 'another_path');
  293. $this->assertEquals($expected, $result);
  294. $result = Folder::addPathElement(DS . 'some' . DS . 'dir' . DS, 'another_path');
  295. $this->assertEquals($expected, $result);
  296. $result = Folder::addPathElement(DS . 'some' . DS . 'dir', ['another_path']);
  297. $this->assertEquals($expected, $result);
  298. $result = Folder::addPathElement(DS . 'some' . DS . 'dir' . DS, ['another_path']);
  299. $this->assertEquals($expected, $result);
  300. $expected = DS . 'some' . DS . 'dir' . DS . 'another_path' . DS . 'and' . DS . 'another';
  301. $result = Folder::addPathElement(DS . 'some' . DS . 'dir', ['another_path', 'and', 'another']);
  302. $this->assertEquals($expected, $result);
  303. }
  304. /**
  305. * testFolderRead method
  306. *
  307. * @return void
  308. */
  309. public function testFolderRead()
  310. {
  311. $Folder = new Folder(CAKE);
  312. $result = $Folder->read(true, true);
  313. $this->assertContains('Core', $result[0]);
  314. $this->assertContains('Cache', $result[0]);
  315. $Folder = new Folder(TMP . 'non-existent');
  316. $expected = [[], []];
  317. $result = $Folder->read(true, true);
  318. $this->assertEquals($expected, $result);
  319. }
  320. /**
  321. * testFolderReadWithHiddenFiles method
  322. *
  323. * @return void
  324. */
  325. public function testFolderReadWithHiddenFiles()
  326. {
  327. $this->skipIf(!is_writable(TMP), 'Cant test Folder::read with hidden files unless the tmp folder is writable.');
  328. $path = TMP . 'tests' . DS;
  329. $Folder = new Folder($path . 'folder_tree_hidden', true, 0777);
  330. mkdir($Folder->path . DS . '.svn');
  331. mkdir($Folder->path . DS . 'some_folder');
  332. touch($Folder->path . DS . 'not_hidden.txt');
  333. touch($Folder->path . DS . '.hidden.txt');
  334. $expected = [
  335. ['some_folder'],
  336. ['not_hidden.txt'],
  337. ];
  338. $result = $Folder->read(true, true);
  339. $this->assertEquals($expected, $result);
  340. $expected = [
  341. [
  342. '.svn',
  343. 'some_folder'
  344. ],
  345. [
  346. '.hidden.txt',
  347. 'not_hidden.txt'
  348. ],
  349. ];
  350. $result = $Folder->read(true);
  351. $this->assertEquals($expected, $result);
  352. }
  353. /**
  354. * testFolderTree method
  355. *
  356. * @return void
  357. */
  358. public function testFolderTree()
  359. {
  360. $Folder = new Folder();
  361. $expected = [
  362. [
  363. CORE_PATH . 'config',
  364. ],
  365. [
  366. CORE_PATH . 'config' . DS . 'config.php',
  367. ]
  368. ];
  369. $result = $Folder->tree(CORE_PATH . 'config', false);
  370. $this->assertSame([], array_diff($expected[0], $result[0]));
  371. $this->assertSame([], array_diff($result[0], $expected[0]));
  372. $result = $Folder->tree(CORE_PATH . 'config', false, 'dir');
  373. $this->assertSame([], array_diff($expected[0], $result));
  374. $this->assertSame([], array_diff($expected[0], $result));
  375. $result = $Folder->tree(CORE_PATH . 'config', false, 'files');
  376. $this->assertSame([], array_diff($expected[1], $result));
  377. $this->assertSame([], array_diff($expected[1], $result));
  378. }
  379. /**
  380. * testFolderTreeWithHiddenFiles method
  381. *
  382. * @return void
  383. */
  384. public function testFolderTreeWithHiddenFiles()
  385. {
  386. $this->skipIf(!is_writable(TMP), 'Can\'t test Folder::tree with hidden files unless the tmp folder is writable.');
  387. $path = TMP . 'tests' . DS;
  388. $Folder = new Folder($path . 'folder_tree_hidden', true, 0777);
  389. mkdir($Folder->path . DS . '.svn', 0777, true);
  390. touch($Folder->path . DS . '.svn/InHiddenFolder.php');
  391. mkdir($Folder->path . DS . '.svn/inhiddenfolder');
  392. touch($Folder->path . DS . '.svn/inhiddenfolder/NestedInHiddenFolder.php');
  393. touch($Folder->path . DS . 'not_hidden.txt');
  394. touch($Folder->path . DS . '.hidden.txt');
  395. mkdir($Folder->path . DS . 'visible_folder/.git', 0777, true);
  396. $expected = [
  397. [
  398. $Folder->path,
  399. $Folder->path . DS . 'visible_folder',
  400. ],
  401. [
  402. $Folder->path . DS . 'not_hidden.txt',
  403. ],
  404. ];
  405. $result = $Folder->tree(null, true);
  406. $this->assertEquals($expected, $result);
  407. $result = $Folder->tree(null, ['.']);
  408. $this->assertEquals($expected, $result);
  409. $expected = [
  410. [
  411. $Folder->path,
  412. $Folder->path . DS . 'visible_folder',
  413. $Folder->path . DS . 'visible_folder' . DS . '.git',
  414. $Folder->path . DS . '.svn',
  415. $Folder->path . DS . '.svn' . DS . 'inhiddenfolder',
  416. ],
  417. [
  418. $Folder->path . DS . 'not_hidden.txt',
  419. $Folder->path . DS . '.hidden.txt',
  420. $Folder->path . DS . '.svn' . DS . 'inhiddenfolder' . DS . 'NestedInHiddenFolder.php',
  421. $Folder->path . DS . '.svn' . DS . 'InHiddenFolder.php',
  422. ],
  423. ];
  424. $result = $Folder->tree(null, false);
  425. sort($result[0]);
  426. sort($expected[0]);
  427. sort($result[1]);
  428. sort($expected[1]);
  429. $this->assertEquals($expected, $result);
  430. $Folder->delete();
  431. }
  432. /**
  433. * testWindowsPath method
  434. *
  435. * @return void
  436. */
  437. public function testWindowsPath()
  438. {
  439. $this->assertFalse(Folder::isWindowsPath('0:\\cake\\is\\awesome'));
  440. $this->assertTrue(Folder::isWindowsPath('C:\\cake\\is\\awesome'));
  441. $this->assertTrue(Folder::isWindowsPath('d:\\cake\\is\\awesome'));
  442. $this->assertTrue(Folder::isWindowsPath('\\\\vmware-host\\Shared Folders\\file'));
  443. }
  444. /**
  445. * testIsAbsolute method
  446. *
  447. * @return void
  448. */
  449. public function testIsAbsolute()
  450. {
  451. $this->assertFalse(Folder::isAbsolute('path/to/file'));
  452. $this->assertFalse(Folder::isAbsolute('cake/'));
  453. $this->assertFalse(Folder::isAbsolute('path\\to\\file'));
  454. $this->assertFalse(Folder::isAbsolute('0:\\path\\to\\file'));
  455. $this->assertFalse(Folder::isAbsolute('\\path/to/file'));
  456. $this->assertFalse(Folder::isAbsolute('\\path\\to\\file'));
  457. $this->assertFalse(Folder::isAbsolute('notRegisteredStreamWrapper://example'));
  458. $this->assertFalse(Folder::isAbsolute('://example'));
  459. $this->assertTrue(Folder::isAbsolute('/usr/local'));
  460. $this->assertTrue(Folder::isAbsolute('//path/to/file'));
  461. $this->assertTrue(Folder::isAbsolute('C:\\cake'));
  462. $this->assertTrue(Folder::isAbsolute('C:\\path\\to\\file'));
  463. $this->assertTrue(Folder::isAbsolute('d:\\path\\to\\file'));
  464. $this->assertTrue(Folder::isAbsolute('\\\\vmware-host\\Shared Folders\\file'));
  465. $this->assertTrue(Folder::isAbsolute('http://www.example.com'));
  466. }
  467. /**
  468. * testIsSlashTerm method
  469. *
  470. * @return void
  471. */
  472. public function testIsSlashTerm()
  473. {
  474. $this->assertFalse(Folder::isSlashTerm('cake'));
  475. $this->assertTrue(Folder::isSlashTerm('C:\\cake\\'));
  476. $this->assertTrue(Folder::isSlashTerm('/usr/local/'));
  477. }
  478. /**
  479. * testStatic method
  480. *
  481. * @return void
  482. */
  483. public function testSlashTerm()
  484. {
  485. $result = Folder::slashTerm('/path/to/file');
  486. $this->assertEquals('/path/to/file/', $result);
  487. }
  488. /**
  489. * testNormalizePath method
  490. *
  491. * @return void
  492. */
  493. public function testNormalizePath()
  494. {
  495. $path = '/path/to/file';
  496. $result = Folder::normalizePath($path);
  497. $this->assertEquals('/', $result);
  498. $path = '\\path\\\to\\\file';
  499. $result = Folder::normalizePath($path);
  500. $this->assertEquals('/', $result);
  501. $path = 'C:\\path\\to\\file';
  502. $result = Folder::normalizePath($path);
  503. $this->assertEquals('\\', $result);
  504. }
  505. /**
  506. * correctSlashFor method
  507. *
  508. * @return void
  509. */
  510. public function testCorrectSlashFor()
  511. {
  512. $path = '/path/to/file';
  513. $result = Folder::correctSlashFor($path);
  514. $this->assertEquals('/', $result);
  515. $path = '\\path\\to\\file';
  516. $result = Folder::correctSlashFor($path);
  517. $this->assertEquals('/', $result);
  518. $path = 'C:\\path\to\\file';
  519. $result = Folder::correctSlashFor($path);
  520. $this->assertEquals('\\', $result);
  521. }
  522. /**
  523. * testInCakePath method
  524. *
  525. * @return void
  526. */
  527. public function testInCakePath()
  528. {
  529. $Folder = new Folder();
  530. $Folder->cd(ROOT);
  531. $path = 'C:\\path\\to\\file';
  532. $result = $Folder->inCakePath($path);
  533. $this->assertFalse($result);
  534. $path = ROOT;
  535. $Folder->cd(ROOT);
  536. $result = $Folder->inCakePath($path);
  537. $this->assertFalse($result);
  538. $path = DS . 'config';
  539. $Folder->cd(ROOT . DS . 'config');
  540. $result = $Folder->inCakePath($path);
  541. $this->assertTrue($result);
  542. }
  543. /**
  544. * testFind method
  545. *
  546. * @return void
  547. */
  548. public function testFind()
  549. {
  550. $Folder = new Folder();
  551. $Folder->cd(CORE_PATH . 'config');
  552. $result = $Folder->find();
  553. $expected = ['config.php'];
  554. $this->assertSame(array_diff($expected, $result), []);
  555. $this->assertSame(array_diff($expected, $result), []);
  556. $result = $Folder->find('.*', true);
  557. $expected = ['bootstrap.php', 'cacert.pem', 'config.php'];
  558. $this->assertSame($expected, $result);
  559. $result = $Folder->find('.*\.php');
  560. $expected = ['bootstrap.php', 'config.php'];
  561. $this->assertSame(array_diff($expected, $result), []);
  562. $this->assertSame(array_diff($expected, $result), []);
  563. $result = $Folder->find('.*\.php', true);
  564. $expected = ['bootstrap.php', 'config.php'];
  565. $this->assertSame($expected, $result);
  566. $result = $Folder->find('.*ig\.php');
  567. $expected = ['config.php'];
  568. $this->assertSame($expected, $result);
  569. $result = $Folder->find('config\.php');
  570. $expected = ['config.php'];
  571. $this->assertSame($expected, $result);
  572. $Folder = new Folder(TMP . 'tests/', true);
  573. $File = new File($Folder->pwd() . DS . 'paths.php', true);
  574. $Folder->create($Folder->pwd() . DS . 'testme');
  575. $Folder->cd('testme');
  576. $result = $Folder->find('paths\.php');
  577. $expected = [];
  578. $this->assertSame($expected, $result);
  579. $Folder->cd($Folder->pwd() . '/..');
  580. $result = $Folder->find('paths\.php');
  581. $expected = ['paths.php'];
  582. $this->assertSame($expected, $result);
  583. }
  584. /**
  585. * testFindRecursive method
  586. *
  587. * @return void
  588. */
  589. public function testFindRecursive()
  590. {
  591. $Folder = new Folder(CORE_PATH);
  592. $result = $Folder->findRecursive('(config|paths)\.php');
  593. $expected = [
  594. CORE_PATH . 'config' . DS . 'config.php'
  595. ];
  596. $this->assertSame([], array_diff($expected, $result));
  597. $this->assertSame([], array_diff($expected, $result));
  598. $result = $Folder->findRecursive('(config|woot)\.php', true);
  599. $expected = [
  600. CORE_PATH . 'config' . DS . 'config.php'
  601. ];
  602. $this->assertSame($expected, $result);
  603. $path = TMP . 'tests' . DS;
  604. $Folder = new Folder($path, true);
  605. $Folder->create($path . 'sessions');
  606. $Folder->create($path . 'testme');
  607. $Folder->cd($path . 'testme');
  608. $File = new File($Folder->pwd() . DS . 'paths.php');
  609. $File->create();
  610. $Folder->cd($path . 'sessions');
  611. $result = $Folder->findRecursive('paths\.php');
  612. $expected = [];
  613. $this->assertSame($expected, $result);
  614. $Folder->cd($path . 'testme');
  615. $File = new File($Folder->pwd() . DS . 'my.php');
  616. $File->create();
  617. $Folder->cd($path);
  618. $result = $Folder->findRecursive('(paths|my)\.php');
  619. $expected = [
  620. $path . 'testme' . DS . 'my.php',
  621. $path . 'testme' . DS . 'paths.php'
  622. ];
  623. $this->assertSame(sort($expected), sort($result));
  624. $result = $Folder->findRecursive('(paths|my)\.php', true);
  625. $expected = [
  626. $path . 'testme' . DS . 'my.php',
  627. $path . 'testme' . DS . 'paths.php'
  628. ];
  629. $this->assertSame($expected, $result);
  630. }
  631. /**
  632. * testConstructWithNonExistentPath method
  633. *
  634. * @return void
  635. */
  636. public function testConstructWithNonExistentPath()
  637. {
  638. $path = TMP . 'tests' . DS;
  639. $Folder = new Folder($path . 'config_non_existent', true);
  640. $this->assertTrue(is_dir($path . 'config_non_existent'));
  641. $Folder->cd($path);
  642. }
  643. /**
  644. * testDirSize method
  645. *
  646. * @return void
  647. */
  648. public function testDirSize()
  649. {
  650. $path = TMP . 'tests' . DS;
  651. $Folder = new Folder($path . 'config_non_existent', true);
  652. $this->assertEquals(0, $Folder->dirSize());
  653. $File = new File($Folder->pwd() . DS . 'my.php', true, 0777);
  654. $File->create();
  655. $File->write('something here');
  656. $File->close();
  657. $this->assertEquals(14, $Folder->dirSize());
  658. }
  659. /**
  660. * test that errors and messages can be resetted
  661. *
  662. * @return void
  663. */
  664. public function testReset()
  665. {
  666. $path = TMP . 'tests' . DS . 'folder_delete_test';
  667. mkdir($path, 0777, true);
  668. $folder = $path . DS . 'sub';
  669. mkdir($folder);
  670. $file = $folder . DS . 'file';
  671. touch($file);
  672. chmod($folder, 0555);
  673. chmod($file, 0444);
  674. $Folder = new Folder($folder);
  675. $return = $Folder->delete();
  676. $this->assertFalse($return);
  677. $messages = $Folder->messages();
  678. $errors = $Folder->errors();
  679. $expected = [
  680. $file . ' NOT removed',
  681. $folder . ' NOT removed',
  682. ];
  683. sort($expected);
  684. sort($errors);
  685. $this->assertEmpty($messages);
  686. $this->assertEquals($expected, $errors);
  687. chmod($file, 0644);
  688. chmod($folder, 0755);
  689. $return = $Folder->delete();
  690. $this->assertTrue($return);
  691. $messages = $Folder->messages();
  692. $errors = $Folder->errors();
  693. $expected = [
  694. $file . ' removed',
  695. $folder . ' removed',
  696. ];
  697. sort($expected);
  698. sort($messages);
  699. $this->assertEmpty($errors);
  700. $this->assertEquals($expected, $messages);
  701. }
  702. /**
  703. * testDelete method
  704. *
  705. * @return void
  706. */
  707. public function testDelete()
  708. {
  709. $path = TMP . 'tests' . DS . 'folder_delete_test';
  710. mkdir($path, 0777, true);
  711. touch($path . DS . 'file_1');
  712. mkdir($path . DS . 'level_1_1');
  713. touch($path . DS . 'level_1_1/file_1_1');
  714. mkdir($path . DS . 'level_1_1/level_2_1');
  715. touch($path . DS . 'level_1_1/level_2_1/file_2_1');
  716. touch($path . DS . 'level_1_1/level_2_1/file_2_2');
  717. mkdir($path . DS . 'level_1_1/level_2_2');
  718. $Folder = new Folder($path, true);
  719. $return = $Folder->delete();
  720. $this->assertTrue($return);
  721. $messages = $Folder->messages();
  722. $errors = $Folder->errors();
  723. $this->assertEquals([], $errors);
  724. $expected = [
  725. $path . DS . 'file_1 removed',
  726. $path . DS . 'level_1_1' . DS . 'file_1_1 removed',
  727. $path . DS . 'level_1_1' . DS . 'level_2_1' . DS . 'file_2_1 removed',
  728. $path . DS . 'level_1_1' . DS . 'level_2_1' . DS . 'file_2_2 removed',
  729. $path . DS . 'level_1_1' . DS . 'level_2_1 removed',
  730. $path . DS . 'level_1_1' . DS . 'level_2_2 removed',
  731. $path . DS . 'level_1_1 removed',
  732. $path . ' removed'
  733. ];
  734. sort($expected);
  735. sort($messages);
  736. $this->assertEquals($expected, $messages);
  737. }
  738. /**
  739. * testCopy method
  740. *
  741. * Verify that subdirectories existing in both destination and source directory
  742. * are merged recursively.
  743. *
  744. * @return void
  745. */
  746. public function testCopy()
  747. {
  748. extract($this->_setupFilesystem());
  749. $Folder = new Folder($folderOne);
  750. $result = $Folder->copy($folderThree);
  751. $this->assertTrue($result);
  752. $this->assertTrue(file_exists($folderThree . DS . 'file1.php'));
  753. $this->assertTrue(file_exists($folderThree . DS . 'folderA' . DS . 'fileA.php'));
  754. $Folder = new Folder($folderTwo);
  755. $result = $Folder->copy($folderThree);
  756. $this->assertTrue($result);
  757. $this->assertTrue(file_exists($folderThree . DS . 'file1.php'));
  758. $this->assertTrue(file_exists($folderThree . DS . 'file2.php'));
  759. $this->assertTrue(file_exists($folderThree . DS . 'folderA' . DS . 'fileA.php'));
  760. $this->assertTrue(file_exists($folderThree . DS . 'folderB' . DS . 'fileB.php'));
  761. $Folder = new Folder($path);
  762. $Folder->delete();
  763. }
  764. /**
  765. * testCopyWithMerge method
  766. *
  767. * Verify that subdirectories existing in both destination and source directory
  768. * are merged recursively.
  769. *
  770. * @return void
  771. */
  772. public function testCopyWithMerge()
  773. {
  774. extract($this->_setupFilesystem());
  775. $Folder = new Folder($folderOne);
  776. $result = $Folder->copy($folderThree);
  777. $this->assertTrue($result);
  778. $this->assertTrue(file_exists($folderThree . DS . 'file1.php'));
  779. $this->assertTrue(file_exists($folderThree . DS . 'folderA' . DS . 'fileA.php'));
  780. $Folder = new Folder($folderTwo);
  781. $result = $Folder->copy(['to' => $folderThree, 'scheme' => Folder::MERGE]);
  782. $this->assertTrue($result);
  783. $this->assertTrue(file_exists($folderThree . DS . 'file1.php'));
  784. $this->assertTrue(file_exists($folderThree . DS . 'file2.php'));
  785. $this->assertTrue(file_exists($folderThree . DS . 'folderA' . DS . 'fileA.php'));
  786. $this->assertTrue(file_exists($folderThree . DS . 'folderB' . DS . 'fileB.php'));
  787. }
  788. /**
  789. * testCopyWithSkip method
  790. *
  791. * Verify that directories and files are copied recursively
  792. * even if the destination directory already exists.
  793. * Subdirectories existing in both destination and source directory
  794. * are skipped and not merged or overwritten.
  795. *
  796. * @return void
  797. */
  798. public function testCopyWithSkip()
  799. {
  800. extract($this->_setupFilesystem());
  801. $Folder = new Folder($folderOne);
  802. $result = $Folder->copy(['to' => $folderTwo, 'scheme' => Folder::SKIP]);
  803. $this->assertTrue($result);
  804. $this->assertTrue(file_exists($folderTwo . DS . 'file1.php'));
  805. $this->assertTrue(file_exists($folderTwo . DS . 'folderA' . DS . 'fileA.php'));
  806. $Folder = new Folder($folderTwo);
  807. $Folder->delete();
  808. $Folder = new Folder($folderOne);
  809. $result = $Folder->copy(['to' => $folderTwo, 'scheme' => Folder::SKIP]);
  810. $this->assertTrue($result);
  811. $this->assertTrue(file_exists($folderTwo . DS . 'file1.php'));
  812. $this->assertTrue(file_exists($folderTwo . DS . 'folderA' . DS . 'fileA.php'));
  813. $Folder = new Folder($folderTwo);
  814. $Folder->delete();
  815. new Folder($folderTwo, true);
  816. new Folder($folderTwo . DS . 'folderB', true);
  817. file_put_contents($folderTwo . DS . 'file2.php', 'touched');
  818. file_put_contents($folderTwo . DS . 'folderB' . DS . 'fileB.php', 'untouched');
  819. $Folder = new Folder($folderTwo);
  820. $result = $Folder->copy(['to' => $folderThree, 'scheme' => Folder::SKIP]);
  821. $this->assertTrue($result);
  822. $this->assertTrue(file_exists($folderThree . DS . 'file2.php'));
  823. $this->assertEquals('touched', file_get_contents($folderThree . DS . 'file2.php'));
  824. $this->assertEquals('untouched', file_get_contents($folderThree . DS . 'folderB' . DS . 'fileB.php'));
  825. }
  826. /**
  827. * Test that SKIP mode skips files too.
  828. *
  829. * @return void
  830. */
  831. public function testCopyWithSkipFileSkipped()
  832. {
  833. $path = TMP . 'folder_test';
  834. $folderOne = $path . DS . 'folder1';
  835. $folderTwo = $path . DS . 'folder2';
  836. new Folder($path, true);
  837. new Folder($folderOne, true);
  838. new Folder($folderTwo, true);
  839. file_put_contents($folderOne . DS . 'fileA.txt', 'Folder One File');
  840. file_put_contents($folderTwo . DS . 'fileA.txt', 'Folder Two File');
  841. $Folder = new Folder($folderOne);
  842. $result = $Folder->copy(['to' => $folderTwo, 'scheme' => Folder::SKIP]);
  843. $this->assertTrue($result);
  844. $this->assertEquals('Folder Two File', file_get_contents($folderTwo . DS . 'fileA.txt'));
  845. }
  846. /**
  847. * testCopyWithOverwrite
  848. *
  849. * Verify that subdirectories existing in both destination and source directory
  850. * are overwritten/replaced recursively.
  851. *
  852. * @return void
  853. */
  854. public function testCopyWithOverwrite()
  855. {
  856. extract($this->_setupFilesystem());
  857. $Folder = new Folder($folderOne);
  858. $result = $Folder->copy(['to' => $folderThree, 'scheme' => Folder::OVERWRITE]);
  859. $this->assertTrue(file_exists($folderThree . DS . 'file1.php'));
  860. $this->assertTrue(file_exists($folderThree . DS . 'folderA' . DS . 'fileA.php'));
  861. $Folder = new Folder($folderTwo);
  862. $result = $Folder->copy(['to' => $folderThree, 'scheme' => Folder::OVERWRITE]);
  863. $this->assertTrue($result);
  864. $this->assertTrue(file_exists($folderThree . DS . 'folderA' . DS . 'fileA.php'));
  865. $Folder = new Folder($folderOne);
  866. unlink($fileOneA);
  867. $result = $Folder->copy(['to' => $folderThree, 'scheme' => Folder::OVERWRITE]);
  868. $this->assertTrue($result);
  869. $this->assertTrue(file_exists($folderThree . DS . 'file1.php'));
  870. $this->assertTrue(file_exists($folderThree . DS . 'file2.php'));
  871. $this->assertTrue(!file_exists($folderThree . DS . 'folderA' . DS . 'fileA.php'));
  872. $this->assertTrue(file_exists($folderThree . DS . 'folderB' . DS . 'fileB.php'));
  873. }
  874. /**
  875. * Setup filesystem for copy tests
  876. * $path: folder_test/
  877. * - folder1/file1.php
  878. * - folder1/folderA/fileA.php
  879. * - folder2/file2.php
  880. * - folder2/folderB/fileB.php
  881. * - folder3/
  882. *
  883. * @return array Filenames to extract in the test methods
  884. */
  885. protected function _setupFilesystem()
  886. {
  887. $path = TMP . 'tests';
  888. $folderOne = $path . DS . 'folder1';
  889. $folderOneA = $folderOne . DS . 'folderA';
  890. $folderTwo = $path . DS . 'folder2';
  891. $folderTwoB = $folderTwo . DS . 'folderB';
  892. $folderThree = $path . DS . 'folder3';
  893. $fileOne = $folderOne . DS . 'file1.php';
  894. $fileTwo = $folderTwo . DS . 'file2.php';
  895. $fileOneA = $folderOneA . DS . 'fileA.php';
  896. $fileTwoB = $folderTwoB . DS . 'fileB.php';
  897. new Folder($path, true);
  898. new Folder($folderOne, true);
  899. new Folder($folderOneA, true);
  900. new Folder($folderTwo, true);
  901. new Folder($folderTwoB, true);
  902. new Folder($folderThree, true);
  903. touch($fileOne);
  904. touch($fileTwo);
  905. touch($fileOneA);
  906. touch($fileTwoB);
  907. return compact(
  908. 'path',
  909. 'folderOne',
  910. 'folderOneA',
  911. 'folderTwo',
  912. 'folderTwoB',
  913. 'folderThree',
  914. 'fileOne',
  915. 'fileOneA',
  916. 'fileTwo',
  917. 'fileTwoB'
  918. );
  919. }
  920. /**
  921. * testMove method
  922. *
  923. * Verify that directories and files are moved recursively
  924. * even if the destination directory already exists.
  925. * Subdirectories existing in both destination and source directory
  926. * are merged recursively.
  927. *
  928. * @return void
  929. */
  930. public function testMove()
  931. {
  932. extract($this->_setupFilesystem());
  933. $Folder = new Folder($folderOne);
  934. $result = $Folder->move($folderTwo);
  935. $this->assertTrue($result);
  936. $this->assertTrue(file_exists($folderTwo . '/file1.php'));
  937. $this->assertTrue(is_dir($folderTwo . '/folderB'));
  938. $this->assertTrue(file_exists($folderTwo . '/folderB/fileB.php'));
  939. $this->assertFalse(file_exists($fileOne));
  940. $this->assertTrue(file_exists($folderTwo . '/folderA'));
  941. $this->assertFalse(file_exists($folderOneA));
  942. $this->assertFalse(file_exists($fileOneA));
  943. $Folder = new Folder($folderTwo);
  944. $Folder->delete();
  945. new Folder($folderOne, true);
  946. new Folder($folderOneA, true);
  947. touch($fileOne);
  948. touch($fileOneA);
  949. $Folder = new Folder($folderOne);
  950. $result = $Folder->move($folderTwo);
  951. $this->assertTrue($result);
  952. $this->assertTrue(file_exists($folderTwo . '/file1.php'));
  953. $this->assertTrue(is_dir($folderTwo . '/folderA'));
  954. $this->assertTrue(file_exists($folderTwo . '/folderA/fileA.php'));
  955. $this->assertFalse(file_exists($fileOne));
  956. $this->assertFalse(file_exists($folderOneA));
  957. $this->assertFalse(file_exists($fileOneA));
  958. $Folder = new Folder($folderTwo);
  959. $Folder->delete();
  960. new Folder($folderOne, true);
  961. new Folder($folderOneA, true);
  962. new Folder($folderTwo, true);
  963. new Folder($folderTwoB, true);
  964. touch($fileOne);
  965. touch($fileOneA);
  966. new Folder($folderOne . '/folderB', true);
  967. touch($folderOne . '/folderB/fileB.php');
  968. file_put_contents($folderTwoB . '/fileB.php', 'untouched');
  969. $Folder = new Folder($folderOne);
  970. $result = $Folder->move($folderTwo);
  971. $this->assertTrue($result);
  972. $this->assertTrue(file_exists($folderTwo . '/file1.php'));
  973. $this->assertEquals('', file_get_contents($folderTwoB . '/fileB.php'));
  974. $this->assertFalse(file_exists($fileOne));
  975. $this->assertFalse(file_exists($folderOneA));
  976. $this->assertFalse(file_exists($fileOneA));
  977. $Folder = new Folder($path);
  978. $Folder->delete();
  979. }
  980. /**
  981. * testMoveWithSkip method
  982. *
  983. * Verify that directories and files are moved recursively
  984. * even if the destination directory already exists.
  985. * Subdirectories existing in both destination and source directory
  986. * are skipped and not merged or overwritten.
  987. *
  988. * @return void
  989. */
  990. public function testMoveWithSkip()
  991. {
  992. extract($this->_setupFilesystem());
  993. $Folder = new Folder($folderOne);
  994. $result = $Folder->move(['to' => $folderTwo, 'scheme' => Folder::SKIP]);
  995. $this->assertTrue($result);
  996. $this->assertTrue(file_exists($folderTwo . '/file1.php'));
  997. $this->assertTrue(is_dir($folderTwo . '/folderB'));
  998. $this->assertTrue(file_exists($folderTwoB . '/fileB.php'));
  999. $this->assertFalse(file_exists($fileOne));
  1000. $this->assertFalse(file_exists($folderOneA));
  1001. $this->assertFalse(file_exists($fileOneA));
  1002. $Folder = new Folder($folderTwo);
  1003. $Folder->delete();
  1004. new Folder($folderOne, true);
  1005. new Folder($folderOneA, true);
  1006. new Folder($folderTwo, true);
  1007. touch($fileOne);
  1008. touch($fileOneA);
  1009. $Folder = new Folder($folderOne);
  1010. $result = $Folder->move(['to' => $folderTwo, 'scheme' => Folder::SKIP]);
  1011. $this->assertTrue($result);
  1012. $this->assertTrue(file_exists($folderTwo . '/file1.php'));
  1013. $this->assertTrue(is_dir($folderTwo . '/folderA'));
  1014. $this->assertTrue(file_exists($folderTwo . '/folderA/fileA.php'));
  1015. $this->assertFalse(file_exists($fileOne));
  1016. $this->assertFalse(file_exists($folderOneA));
  1017. $this->assertFalse(file_exists($fileOneA));
  1018. $Folder = new Folder($folderTwo);
  1019. $Folder->delete();
  1020. new Folder($folderOne, true);
  1021. new Folder($folderOneA, true);
  1022. new Folder($folderTwo, true);
  1023. new Folder($folderTwoB, true);
  1024. touch($fileOne);
  1025. touch($fileOneA);
  1026. file_put_contents($folderTwoB . '/fileB.php', 'untouched');
  1027. $Folder = new Folder($folderOne);
  1028. $result = $Folder->move(['to' => $folderTwo, 'scheme' => Folder::SKIP]);
  1029. $this->assertTrue($result);
  1030. $this->assertTrue(file_exists($folderTwo . '/file1.php'));
  1031. $this->assertEquals('untouched', file_get_contents($folderTwoB . '/fileB.php'));
  1032. $this->assertFalse(file_exists($fileOne));
  1033. $this->assertFalse(file_exists($folderOneA));
  1034. $this->assertFalse(file_exists($fileOneA));
  1035. $Folder = new Folder($path);
  1036. $Folder->delete();
  1037. }
  1038. }