FolderTest.php 32 KB

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