FolderTest.php 34 KB

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