PathTest.php 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154
  1. <?php
  2. namespace Path\Tests;
  3. use Path\Exception\FileExistsException;
  4. use Path\Exception\FileNotFoundException;
  5. use Path\Path;
  6. use PHPUnit\Framework\TestCase;
  7. // TODO: tested args should be both typed Path and string
  8. class PathTest extends TestCase
  9. {
  10. const TEMP_TEST_DIR = __DIR__ . "/temp";
  11. // TODO: consider using sys_get_temp_dir()
  12. protected Path $pathClass;
  13. public function setUp(): void
  14. {
  15. mkdir(self::TEMP_TEST_DIR);
  16. chdir(self::TEMP_TEST_DIR);
  17. }
  18. private function rmDirs(string $dir): void {
  19. // Remove and replace by a proper tempdir method
  20. foreach(scandir($dir) as $file) {
  21. if ('.' === $file || '..' === $file) continue;
  22. if (is_dir($dir . DIRECTORY_SEPARATOR . $file)) $this->rmDirs($dir . DIRECTORY_SEPARATOR . $file);
  23. else unlink($dir . DIRECTORY_SEPARATOR . $file);
  24. }
  25. rmdir($dir);
  26. }
  27. public function tearDown(): void
  28. {
  29. $this->rmDirs(self::TEMP_TEST_DIR);
  30. chdir(__DIR__);
  31. }
  32. public function testToString(): void
  33. {
  34. $path = new Path('/foo/bar');
  35. $this->assertEquals('/foo/bar', $path->__toString());
  36. }
  37. /**
  38. * Test 'join' method.
  39. */
  40. public function testJoin(): void
  41. {
  42. // One part
  43. $this->assertEquals(
  44. '/home/user',
  45. Path::join('/home', 'user')
  46. );
  47. // Multiple parts
  48. $this->assertEquals(
  49. '/home/user/documents',
  50. Path::join('/home', 'user', 'documents')
  51. );
  52. // Absolute path passed in $parts
  53. $this->assertEquals(
  54. '/user/documents',
  55. Path::join('home', '/user', 'documents')
  56. );
  57. }
  58. /**
  59. * Test 'Path' class 'copy_dir' method to copy a directory
  60. *
  61. * @return void
  62. * @throws FileExistsException
  63. * @throws FileNotFoundException
  64. */
  65. public function testCopyDir(): void
  66. {
  67. $src = self::TEMP_TEST_DIR . "/some_dir";
  68. $srcContent = $src . DIRECTORY_SEPARATOR . "foo.txt";
  69. $dst = self::TEMP_TEST_DIR . "/some_other_dir";
  70. mkdir($src);
  71. touch($srcContent);
  72. mkdir($dst);
  73. Path::copy_dir($src, $dst);
  74. $this->assertTrue(
  75. file_exists($dst . DIRECTORY_SEPARATOR . "foo.txt")
  76. );
  77. }
  78. /**
  79. * Test 'Path' class 'copy_dir' method when the destination directory does not exist
  80. *
  81. * @throws FileNotFoundException|FileExistsException
  82. */
  83. public function testCopyDirWhenDestinationDirectoryNotExists(): void
  84. {
  85. $src = self::TEMP_TEST_DIR . "/some_dir";
  86. $dst = self::TEMP_TEST_DIR . "/non_existing_dir";
  87. mkdir($src);
  88. touch($src . DIRECTORY_SEPARATOR . "foo.txt");
  89. $this->expectException(FileNotFoundException::class);
  90. $this->expectExceptionMessage("Directory does not exist : " . $dst);
  91. Path::copy_dir($src, $dst);
  92. }
  93. /**
  94. * Test 'Path' class 'copy_dir' method when the destination directory already exists.
  95. *
  96. * @throws FileNotFoundException|FileExistsException if the destination directory already exists.
  97. */
  98. public function testCopyDirWhenDirectoryAlreadyExistsAtDestination(): void
  99. {
  100. $src = self::TEMP_TEST_DIR . "/some_dir";
  101. $dst = self::TEMP_TEST_DIR . "/other_dir";
  102. mkdir($src);
  103. touch($src . DIRECTORY_SEPARATOR . "foo.txt");
  104. mkdir($dst);
  105. mkdir($dst . DIRECTORY_SEPARATOR . "some_dir");
  106. $this->expectException(FileExistsException::class);
  107. $this->expectExceptionMessage("Directory already exists : " . $dst);
  108. Path::copy_dir($src, $dst);
  109. }
  110. /**
  111. * Test `eq` method with equal paths.
  112. *
  113. * Check that the method returns the correct result when the paths are equal.
  114. */
  115. public function testEqWithEqualPaths(): void
  116. {
  117. $path = new Path('/foo/bar');
  118. $this->assertTrue($path->eq('/foo/bar'));
  119. }
  120. /**
  121. * Test `eq` method with different paths.
  122. *
  123. * Check that the method returns the correct result when the paths are different.
  124. */
  125. public function testEqWithDifferentPaths(): void
  126. {
  127. $path = new Path('/foo/bar');
  128. $this->assertFalse($path->eq('/foo/zzz'));
  129. }
  130. /**
  131. * Test `eq` method with empty path.
  132. *
  133. * Check that the method returns the correct result when the path is empty.
  134. */
  135. public function testEqWithEmptyPath(): void
  136. {
  137. $path = new Path('/foo/bar');
  138. $this->assertFalse($path->eq(''));
  139. }
  140. /**
  141. * Test the append method of the Path class.
  142. *
  143. * @return void
  144. */
  145. public function testAppend(): void
  146. {
  147. $path = new Path('/foo');
  148. $this->assertEquals(
  149. "/foo/bar",
  150. $path->append('bar')
  151. );
  152. // One part
  153. $this->assertTrue(
  154. (new Path('/home'))->append('user')->eq('/home/user')
  155. );
  156. // Multiple parts
  157. $this->assertTrue(
  158. (new Path('/home'))->append('user', 'documents')->eq('/home/user/documents')
  159. );
  160. // Absolute path passed in $parts
  161. $this->assertTrue(
  162. (new Path('/home'))->append('/user', 'documents')->eq('/user/documents')
  163. );
  164. }
  165. /**
  166. * Test the abspath method of the Path class.
  167. *
  168. * @return void
  169. */
  170. public function testAbsPath(): void
  171. {
  172. touch(self::TEMP_TEST_DIR . "/foo");
  173. chdir(self::TEMP_TEST_DIR);
  174. $this->assertEquals(
  175. self::TEMP_TEST_DIR . "/foo",
  176. (new Path('foo'))->abspath()
  177. );
  178. }
  179. /**
  180. * Test the abspath method of the Path class with a relative path.
  181. *
  182. * @return void
  183. */
  184. public function testAbsPathWithRelative(): void
  185. {
  186. mkdir(self::TEMP_TEST_DIR . "/foo");
  187. touch(self::TEMP_TEST_DIR . "/bar");
  188. chdir(self::TEMP_TEST_DIR . "/foo");
  189. $this->assertEquals(
  190. self::TEMP_TEST_DIR . "/bar",
  191. (new Path('../bar'))->abspath()
  192. );
  193. }
  194. /**
  195. * Test 'Path' class 'access' method to check existence of the file
  196. */
  197. public function testAccessCheckExistenceOfFile(): void
  198. {
  199. $filePath = self::TEMP_TEST_DIR . "/foo";
  200. touch($filePath);
  201. chmod($filePath, 777);
  202. $result = (new Path('foo'))->access(Path::F_OK);
  203. $this->assertTrue($result);
  204. }
  205. /**
  206. * Test 'Path' class 'access' method to check existence of the non-existent file
  207. */
  208. public function testAccessCheckExistenceOfNonExistingFile(): void
  209. {
  210. $result = (new Path('foo'))->access(Path::F_OK);
  211. $this->assertFalse($result);
  212. }
  213. /**
  214. * Test 'Path' class 'access' method to check read permission of the file
  215. */
  216. public function testAccessCheckReadPermissionOfFile(): void
  217. {
  218. $filePath = self::TEMP_TEST_DIR . "/foo";
  219. touch($filePath);
  220. chmod($filePath, 777);
  221. $result = (new Path('foo'))->access(Path::R_OK);
  222. $this->assertTrue($result);
  223. }
  224. // /**
  225. // * Test 'Path' class 'access' method to check read permission of the file (no permission)
  226. // */
  227. // public function testAccessCheckReadPermissionOfFileNoRight(): void
  228. // {
  229. // $filePath = self::TEMP_TEST_DIR . "/foo";
  230. // touch($filePath);
  231. // chmod($filePath, 000);
  232. //
  233. // $result = (new Path('foo'))->access(Path::R_OK);
  234. // $this->assertFalse($result);
  235. // }
  236. /**
  237. * Test 'Path' class 'access' method to check write permission of the file
  238. */
  239. public function testAccessCheckWritePermissionOfFile(): void
  240. {
  241. $filePath = self::TEMP_TEST_DIR . "/foo";
  242. touch($filePath);
  243. chmod($filePath, 777);
  244. $result = (new Path('foo'))->access(Path::W_OK);
  245. $this->assertTrue($result);
  246. }
  247. // /**
  248. // * Test 'Path' class 'access' method to check write permission of the file (no permission)
  249. // */
  250. // public function testAccessCheckWritePermissionOfFileNoRight(): void
  251. // {
  252. // $filePath = self::TEMP_TEST_DIR . "/foo";
  253. // touch($filePath);
  254. // chmod($filePath, 000);
  255. //
  256. // $result = (new Path('foo'))->access(Path::W_OK);
  257. // $this->assertFalse($result);
  258. // }
  259. /**
  260. * Test 'Path' class 'access' method to check execute permission of the file
  261. */
  262. public function testAccessCheckExecutePermissionOfFile(): void
  263. {
  264. $filePath = self::TEMP_TEST_DIR . "/foo";
  265. touch($filePath);
  266. chmod($filePath, 777);
  267. $result = (new Path('foo'))->access(Path::X_OK);
  268. $this->assertTrue($result);
  269. }
  270. /**
  271. * Test 'Path' class 'access' method to check existence of the file
  272. */
  273. public function testAccessCheckExecutePermissionOfFileNoRight(): void
  274. {
  275. $filePath = self::TEMP_TEST_DIR . "/foo";
  276. touch($filePath);
  277. chmod($filePath, 000);
  278. $result = (new Path('foo'))->access(Path::X_OK);
  279. $this->assertFalse($result);
  280. }
  281. /**
  282. * Test 'Path' class 'access' method with an invalid mode parameter
  283. */
  284. public function testAccessInvalidModeParameter(): void
  285. {
  286. $this->expectException(\RuntimeException::class);
  287. (new Path('foo'))->access(123);
  288. }
  289. /**
  290. * Test 'Path' class 'atime' method to get the access time of a file
  291. *
  292. * @return void
  293. */
  294. public function testATime()
  295. {
  296. touch(self::TEMP_TEST_DIR . "/foo");
  297. $atime = (new Path('foo'))->atime();
  298. $this->assertTrue(abs(time() - strtotime($atime)) <= 60);
  299. $this->assertMatchesRegularExpression(
  300. "/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/",
  301. $atime
  302. );
  303. }
  304. /**
  305. * Test 'Path' class 'isFile' method to check if the file exists
  306. *
  307. * @return void
  308. */
  309. public function testIsFileOnActualFile(): void
  310. {
  311. touch(self::TEMP_TEST_DIR . "/foo");
  312. $this->assertTrue((new Path('foo'))->isFile());
  313. }
  314. /**
  315. * Test 'Path' class 'isFile' method to check if a non-existent file exists
  316. *
  317. * @return void
  318. */
  319. public function testIsFileOnNonExistentFile(): void
  320. {
  321. $this->assertFalse((new Path('foo'))->isFile());
  322. }
  323. /**
  324. * Test 'Path' class 'isFile' method to check if a file exists on the given directory
  325. *
  326. * @return void
  327. */
  328. public function testIsFileOnExistentDir(): void
  329. {
  330. mkdir(self::TEMP_TEST_DIR . "/some_dir");
  331. $this->assertFalse((new Path('some_dir'))->isFile());
  332. }
  333. /**
  334. * Test 'Path' class 'isDir' method to check if the path is a directory
  335. *
  336. * @return void
  337. */
  338. public function testIsDirOnActualDir(): void
  339. {
  340. mkdir(self::TEMP_TEST_DIR . "/some_dir");
  341. $this->assertTrue((new Path('some_dir'))->isDir());
  342. }
  343. /**
  344. * Test 'Path' class 'isDir' method to check if a file's path is a directory
  345. *
  346. * @return void
  347. */
  348. public function testIsDirOnExistentFile(): void
  349. {
  350. touch(self::TEMP_TEST_DIR . "/foo");
  351. $this->assertFalse((new Path('some_dir'))->isDir());
  352. }
  353. /**
  354. * Test 'Path' class 'isDir' method on a non-existent directory
  355. *
  356. * @return void
  357. */
  358. public function testIsDirOnNonExistentDir(): void
  359. {
  360. $this->assertFalse((new Path('some_dir'))->isDir());
  361. }
  362. /**
  363. * Test 'Path' class 'ext' method to get the extension of the file
  364. *
  365. * @return void
  366. */
  367. public function testFileExtension(): void
  368. {
  369. $this->assertEquals(
  370. 'txt',
  371. (new Path("foo.txt"))->ext()
  372. );
  373. }
  374. /**
  375. * Test 'Path' class 'ext' method to get the extension of the file
  376. *
  377. * @return void
  378. */
  379. public function testEmptyExtension(): void
  380. {
  381. $this->assertEquals(
  382. '',
  383. (new Path("foo"))->ext()
  384. );
  385. }
  386. /**
  387. * Test 'Path' class 'basename' method to get the base name of a file
  388. *
  389. * @return void
  390. */
  391. public function testBaseName()
  392. {
  393. touch(self::TEMP_TEST_DIR . "/foo.txt");
  394. $this->assertEquals(
  395. 'foo.txt',
  396. (new Path("foo.txt"))->basename()
  397. );
  398. }
  399. /**
  400. * Test 'Path' class 'name' method to get the name of the file without extension
  401. *
  402. * @return void
  403. */
  404. public function testName()
  405. {
  406. touch(self::TEMP_TEST_DIR . "/foo");
  407. $this->assertEquals(
  408. 'foo',
  409. (new Path("foo"))->name()
  410. );
  411. }
  412. /**
  413. * Test 'Path' class 'name' method to get the name of the file with extension
  414. *
  415. * @return void
  416. */
  417. public function testNameWithExt()
  418. {
  419. touch(self::TEMP_TEST_DIR . "/foo.txt");
  420. $this->assertEquals(
  421. 'foo',
  422. (new Path("foo.txt"))->name()
  423. );
  424. }
  425. /**
  426. * Test 'Path' class 'mkdir' method to create a directory
  427. *
  428. * @return void
  429. * @throws FileExistsException
  430. */
  431. public function testMkDir(): void
  432. {
  433. $path = new Path(self::TEMP_TEST_DIR . "/foo");
  434. $path->mkdir();
  435. $this->assertTrue($path->isDir());
  436. }
  437. /**
  438. * Test 'Path' class 'mkdir' method when directory already exists
  439. *
  440. * @throws FileExistsException If directory already exists
  441. */
  442. public function testMkDirExistingDir(): void {
  443. mkdir(self::TEMP_TEST_DIR . "/foo");
  444. $path = new Path(self::TEMP_TEST_DIR . "/foo");
  445. $this->expectException(FileExistsException::class);
  446. $this->expectExceptionMessage("Directory already exists : " . self::TEMP_TEST_DIR . "/foo");
  447. $path->mkdir();
  448. }
  449. /**
  450. * Test 'Path' class 'mkdir' method to create a directory with existing directory and recursive option
  451. *
  452. * @return void
  453. * @throws FileExistsException
  454. */
  455. public function testMkDirExistingDirAndRecursive(): void {
  456. mkdir(self::TEMP_TEST_DIR . "/foo");
  457. $path = new Path(self::TEMP_TEST_DIR . "/foo");
  458. $path->mkdir(0777, true);
  459. $this->assertTrue($path->isDir());
  460. }
  461. /**
  462. * Test 'Path' class 'mkdir' method to create a directory when a file with the same name already exists
  463. *
  464. * @return void
  465. * @throws FileExistsException When a file with the same name already exists
  466. */
  467. public function testMkDirExistingFile(): void {
  468. touch(self::TEMP_TEST_DIR . "/foo");
  469. $path = new Path(self::TEMP_TEST_DIR . "/foo");
  470. $this->expectException(FileExistsException::class);
  471. $this->expectExceptionMessage("A file with this name already exists : " . self::TEMP_TEST_DIR . "/foo");
  472. $path->mkdir();
  473. }
  474. /**
  475. * Test 'Path' class 'mkdir' method to create a directory recursively
  476. *
  477. * @return void
  478. * @throws FileExistsException
  479. */
  480. public function testMkDirRecursive(): void {
  481. $path = new Path(self::TEMP_TEST_DIR . "/foo/bar");
  482. $path->mkdir(0777, true);
  483. $this->assertTrue($path->isDir());
  484. }
  485. /**
  486. * Test 'Path' class 'delete' method to delete a file.
  487. *
  488. * @return void
  489. * @throws FileNotFoundException
  490. */
  491. public function testDeleteFileSuccess(): void
  492. {
  493. touch(self::TEMP_TEST_DIR . "/foo");
  494. $path = new Path(self::TEMP_TEST_DIR . "/foo");
  495. $this->assertTrue($path->isFile());
  496. $path->delete();
  497. $this->assertFalse($path->isFile());
  498. }
  499. /**
  500. * Test 'Path' class 'delete' method to delete a directory successfully
  501. *
  502. * @return void
  503. * @throws FileNotFoundException
  504. */
  505. public function testDeleteDirSuccess(): void
  506. {
  507. mkdir(self::TEMP_TEST_DIR . "/foo");
  508. $path = new Path(self::TEMP_TEST_DIR . "/foo");
  509. $this->assertTrue($path->isDir());
  510. $path->delete();
  511. $this->assertFalse($path->isDir());
  512. }
  513. /**
  514. * Test 'Path' class 'delete' method to delete a non-existing file or dir
  515. *
  516. * @throws FileNotFoundException When the file does not exist
  517. */
  518. public function testDeleteNonExistingFile(): void
  519. {
  520. $path = new Path(self::TEMP_TEST_DIR . "/foo");
  521. $this->assertFalse($path->isDir());
  522. $this->expectException(FileNotFoundException::class);
  523. $this->expectExceptionMessage("File does not exist : " . self::TEMP_TEST_DIR . "/foo");
  524. $path->delete();
  525. }
  526. /**
  527. * Test 'Path' class 'copy_dir' method to copy a file
  528. *
  529. * @return void
  530. * @throws FileExistsException
  531. * @throws FileNotFoundException
  532. */
  533. public function testCopyWithFile(): void
  534. {
  535. $src = self::TEMP_TEST_DIR . "/some_dir";
  536. $srcContent = $src . DIRECTORY_SEPARATOR . "foo.txt";
  537. $dst = self::TEMP_TEST_DIR . "/some_other_dir";
  538. mkdir($src);
  539. mkdir($dst);
  540. touch($srcContent);
  541. $path = new Path($srcContent);
  542. $path->copy($dst);
  543. $this->assertTrue(
  544. file_exists($dst . DIRECTORY_SEPARATOR . "foo.txt")
  545. );
  546. }
  547. /**
  548. * Test 'Path' class 'copy_dir' method to copy a directory
  549. *
  550. * @return void
  551. * @throws FileExistsException
  552. * @throws FileNotFoundException
  553. */
  554. public function testCopyWithDir(): void
  555. {
  556. $src = self::TEMP_TEST_DIR . "/some_dir";
  557. $srcContent = $src . DIRECTORY_SEPARATOR . "foo.txt";
  558. $dst = self::TEMP_TEST_DIR . "/some_other_dir";
  559. mkdir($src);
  560. mkdir($dst);
  561. touch($srcContent);
  562. $path = new Path($src);
  563. $path->copy($dst);
  564. $this->assertTrue(
  565. file_exists($srcContent)
  566. );
  567. }
  568. /**
  569. * Test 'Path' class 'copy' method when the source file does not exist.
  570. *
  571. * @return void
  572. * @throws FileExistsException
  573. * @throws FileNotFoundException
  574. */
  575. public function testCopyFileNotExists(): void
  576. {
  577. $src = self::TEMP_TEST_DIR . "/some_dir";
  578. $srcContent = $src . DIRECTORY_SEPARATOR . "foo.txt";
  579. $dst = self::TEMP_TEST_DIR . "/some_other_dir";
  580. mkdir($src);
  581. mkdir($dst);
  582. touch($srcContent);
  583. $path = new Path($src);
  584. $path->copy($dst);
  585. $this->assertTrue(
  586. file_exists($srcContent)
  587. );
  588. }
  589. /**
  590. * Test 'Path' class 'copy' method when the source file does not exist.
  591. *
  592. * @return void
  593. * @throws FileExistsException
  594. * @throws FileNotFoundException
  595. */
  596. public function testCopyDirDestAlreadyExists(): void
  597. {
  598. $src = self::TEMP_TEST_DIR . "/some_dir";
  599. $srcContent = $src . DIRECTORY_SEPARATOR . "foo.txt";
  600. $dst = self::TEMP_TEST_DIR . "/some_other_dir";
  601. $dstContent = $dst . DIRECTORY_SEPARATOR . "foo.txt";
  602. mkdir($src);
  603. touch($srcContent);
  604. mkdir($dst);
  605. mkdir($dstContent);
  606. $this->expectException(FileExistsException::class);
  607. $this->expectExceptionMessage("File or dir already exists : " . $dstContent);
  608. $path = new Path($srcContent);
  609. $path->copy($dst);
  610. }
  611. /**
  612. * Test 'Path' class 'copy' method when the source file does not exist.
  613. *
  614. * @return void
  615. * @throws FileExistsException
  616. * @throws FileNotFoundException
  617. */
  618. public function testCopyFileDestAlreadyExists(): void
  619. {
  620. $src = self::TEMP_TEST_DIR . "/some_dir";
  621. $srcContent = $src . DIRECTORY_SEPARATOR . "foo.txt";
  622. $dst = self::TEMP_TEST_DIR . "/some_other_dir";
  623. $dstContent = $dst . DIRECTORY_SEPARATOR . "foo.txt";
  624. mkdir($src);
  625. touch($srcContent);
  626. mkdir($dst);
  627. touch($dstContent);
  628. $this->expectException(FileExistsException::class);
  629. $this->expectExceptionMessage("File or dir already exists : " . $dstContent);
  630. $path = new Path($srcContent);
  631. $path->copy($dst);
  632. }
  633. /**
  634. * Test 'Path' class 'move' method to move a file from source directory to destination directory
  635. * @throws FileExistsException
  636. */
  637. public function testMoveWithFile(): void
  638. {
  639. $src = self::TEMP_TEST_DIR . "/some_dir";
  640. $srcContent = $src . DIRECTORY_SEPARATOR . "foo.txt";
  641. $dst = self::TEMP_TEST_DIR . "/some_other_dir";
  642. $dstContent = $dst . DIRECTORY_SEPARATOR . "foo.txt";
  643. mkdir($src);
  644. touch($srcContent);
  645. mkdir($dst);
  646. $path = new Path($srcContent);
  647. $path->move($dst);
  648. $this->assertFalse(
  649. file_exists($srcContent)
  650. );
  651. $this->assertTrue(
  652. file_exists($dstContent)
  653. );
  654. }
  655. /**
  656. * Test 'Path' class 'move' method to move a directory to a different location
  657. *
  658. * @return void
  659. * @throws FileExistsException
  660. */
  661. public function testMoveWithDir(): void
  662. {
  663. $src = self::TEMP_TEST_DIR . "/some_dir";
  664. $srcContent = $src . DIRECTORY_SEPARATOR . "foo.txt";
  665. $dst = self::TEMP_TEST_DIR . "/some_other_dir";
  666. $dstContent = $dst . DIRECTORY_SEPARATOR . "foo.txt";
  667. mkdir($src);
  668. touch($srcContent);
  669. $path = new Path($src);
  670. $path->move($dst);
  671. $this->assertFalse(
  672. file_exists($srcContent)
  673. );
  674. $this->assertTrue(
  675. file_exists($dstContent)
  676. );
  677. }
  678. /**
  679. * Test 'Path' class 'touch' method to create a file that does not exist
  680. *
  681. * @return void
  682. */
  683. public function testTouchFileDoesNotExist(): void
  684. {
  685. $src = self::TEMP_TEST_DIR . "/foo.txt";
  686. $path = new Path($src);
  687. $this->assertFalse(is_file($src));
  688. $path->touch();
  689. $this->assertTrue(is_file($src));
  690. }
  691. public function testTouchFileExistsNothingChange(): void {
  692. $src = self::TEMP_TEST_DIR . "/foo.txt";
  693. touch($src);
  694. $this->assertTrue(is_file($src));
  695. $path = new Path($src);
  696. $path->touch();
  697. $this->assertTrue(is_file($src));
  698. }
  699. public function testTouchFileExistsUpdateMtimeWithInt(): void {
  700. $src = self::TEMP_TEST_DIR . "/foo.txt";
  701. touch($src);
  702. $path = new Path($src);
  703. $timestamp = 1000;
  704. $path->touch($timestamp);
  705. $this->assertEquals(
  706. $timestamp,
  707. filemtime($src)
  708. );
  709. }
  710. public function testTouchFileExistsUpdateMtimeWithDatetime(): void {
  711. $src = self::TEMP_TEST_DIR . "/foo.txt";
  712. touch($src);
  713. $path = new Path($src);
  714. $dateTime = new \DateTime("2000-01-01");
  715. $path->touch($dateTime);
  716. $this->assertEquals(
  717. $dateTime->getTimestamp(),
  718. filemtime($src)
  719. );
  720. }
  721. public function testTouchFileExistsUpdateAtimeWithInt(): void {
  722. $src = self::TEMP_TEST_DIR . "/foo.txt";
  723. touch($src);
  724. $path = new Path($src);
  725. $timestamp = 1000;
  726. $path->touch($timestamp, $timestamp);
  727. $this->assertEquals(
  728. $timestamp,
  729. fileatime($src)
  730. );
  731. }
  732. public function testTouchFileExistsUpdateAtimeWithDatetime(): void {
  733. $src = self::TEMP_TEST_DIR . "/foo.txt";
  734. touch($src);
  735. $path = new Path($src);
  736. $dateTime = new \DateTime("2000-01-01");
  737. $path->touch($dateTime, $dateTime);
  738. $this->assertEquals(
  739. $dateTime->getTimestamp(),
  740. fileatime($src)
  741. );
  742. }
  743. public function testLastModified(): void {
  744. $src = self::TEMP_TEST_DIR . "/foo.txt";
  745. $dateTime = new \DateTime("2000-01-01");
  746. touch($src, $dateTime->getTimestamp());
  747. $path = new Path($src);
  748. $this->assertEquals(
  749. $dateTime->getTimestamp(),
  750. $path->lastModified()
  751. );
  752. }
  753. /**
  754. * Test 'Path' class 'size' method to get the size of the file
  755. *
  756. * @return void
  757. * @throws FileNotFoundException
  758. */
  759. public function testSize(): void {
  760. $src = self::TEMP_TEST_DIR . "/foo.txt";
  761. file_put_contents($src, "nova");
  762. $path = new Path($src);
  763. $this->assertEquals(
  764. 4,
  765. $path->size()
  766. );
  767. }
  768. /**
  769. * Test 'Path' class 'size' method to get the size of the file
  770. *
  771. * @return void
  772. * @throws FileNotFoundException
  773. */
  774. public function testSizeNotExistingFile(): void {
  775. $src = self::TEMP_TEST_DIR . "/foo.txt";
  776. $path = new Path($src);
  777. $this->expectException(FileNotFoundException::class);
  778. $this->expectExceptionMessage("File does not exist : " . $src);
  779. $path->size();
  780. }
  781. public function testParent(): void
  782. {
  783. $this->assertEquals(
  784. '/foo/bar',
  785. (new Path('/foo/bar/baz'))->parent()
  786. );
  787. $this->assertEquals(
  788. '/foo/bar',
  789. (new Path('/foo/bar/baz.txt'))->parent()
  790. );
  791. $this->assertEquals(
  792. '/',
  793. (new Path('/foo'))->parent()
  794. );
  795. }
  796. /**
  797. * Test 'Path' class 'getContent' method to retrieve the content of a file
  798. *
  799. * @return void
  800. * @throws FileNotFoundException
  801. */
  802. public function testGetContent(): void {
  803. $src = self::TEMP_TEST_DIR . "/foo.txt";
  804. file_put_contents($src, "nova");
  805. $path = new Path($src);
  806. $this->assertEquals(
  807. "nova",
  808. $path->getContent()
  809. );
  810. }
  811. /**
  812. * Test 'Path' class 'getContent' method to get the content of a non-existing file
  813. *
  814. * @throws FileNotFoundException If the file does not exist
  815. */
  816. public function testGetContentNotExistingFile(): void {
  817. $src = self::TEMP_TEST_DIR . "/foo.txt";
  818. $path = new Path($src);
  819. $this->expectException(FileNotFoundException::class);
  820. $this->expectExceptionMessage("File does not exist : " . $src);
  821. $path->getContent();
  822. }
  823. public function testPutContent(): void {
  824. $src = self::TEMP_TEST_DIR . "/foo.txt";
  825. $path = new Path($src);
  826. $path->putContent("ocarina");
  827. $this->assertEquals(
  828. "ocarina",
  829. file_get_contents($src)
  830. );
  831. }
  832. public function testAppendContent(): void {
  833. $src = self::TEMP_TEST_DIR . "/foo.txt";
  834. touch($src);
  835. file_put_contents($src, "oca");
  836. $path = new Path($src);
  837. $path->appendContent("rina");
  838. $this->assertEquals(
  839. "ocarina",
  840. file_get_contents($src)
  841. );
  842. }
  843. /**
  844. * Test 'Path' class 'getPermissions' method to retrieve the file permissions
  845. *
  846. * @return void
  847. * @throws FileNotFoundException
  848. */
  849. public function testGetPermissions(): void
  850. {
  851. $src = self::TEMP_TEST_DIR . "/foo.txt";
  852. touch($src);
  853. chmod($src, 0777);
  854. $path = new Path($src);
  855. $this->assertEquals(
  856. 777,
  857. $path->getPermissions()
  858. );
  859. }
  860. /**
  861. * Test 'Path' class 'getPermissions' method to retrieve file permissions
  862. * @throws FileNotFoundException
  863. */
  864. public function testGetPermissionsAlt(): void
  865. {
  866. $src = self::TEMP_TEST_DIR . "/foo.txt";
  867. touch($src);
  868. chmod($src, 0755);
  869. $path = new Path($src);
  870. $this->assertEquals(
  871. 755,
  872. $path->getPermissions()
  873. );
  874. }
  875. /**
  876. * Test 'Path' class 'getPermissions' method to retrieve file permissions
  877. * @throws FileNotFoundException
  878. */
  879. public function testGetPermissionsFileNotExists(): void
  880. {
  881. $src = self::TEMP_TEST_DIR . "/foo.txt";
  882. $path = new Path($src);
  883. $this->expectException(FileNotFoundException::class);
  884. $this->expectExceptionMessage("File or dir does not exist : " . $src);
  885. $path->getPermissions();
  886. }
  887. /**
  888. * Test 'Path' class 'setPermissions' method to change the permissions of a file
  889. * @throws FileNotFoundException
  890. */
  891. public function testSetPermissions(): void
  892. {
  893. $src = self::TEMP_TEST_DIR . "/foo.txt";
  894. touch($src);
  895. chmod($src, 0777);
  896. $path = new Path($src);
  897. $result = $path->setPermissions(0666);
  898. $this->assertTrue($result);
  899. $this->assertEquals(
  900. '0666',
  901. substr(sprintf('%o', fileperms($src)), -4)
  902. );
  903. }
  904. /**
  905. * Test 'Path' class 'setPermissions' method when file does not exist
  906. *
  907. * @throws FileNotFoundException If the file does not exist
  908. */
  909. public function testSetPermissionsFileNotExists(): void
  910. {
  911. $src = self::TEMP_TEST_DIR . "/foo.txt";
  912. $path = new Path($src);
  913. $this->expectException(FileNotFoundException::class);
  914. $this->expectExceptionMessage("File or dir does not exist : " . $src);
  915. $path->setPermissions(777);
  916. }
  917. public function testExistsExistingFile(): void
  918. {
  919. $src = self::TEMP_TEST_DIR . "/foo.txt";
  920. touch($src);
  921. $path = new Path($src);
  922. $this->assertTrue(
  923. $path->exists()
  924. );
  925. }
  926. public function testExistsExistingDir(): void
  927. {
  928. $src = self::TEMP_TEST_DIR . "/foo";
  929. mkdir($src);
  930. $path = new Path($src);
  931. $this->assertTrue(
  932. $path->exists()
  933. );
  934. }
  935. public function testExistsNonExistingFile(): void
  936. {
  937. $src = self::TEMP_TEST_DIR . "/foo.txt";
  938. $path = new Path($src);
  939. $this->assertFalse(
  940. $path->exists()
  941. );
  942. }
  943. public function testGlob(): void
  944. {
  945. $src = self::TEMP_TEST_DIR;
  946. touch($src . "/foo.txt");
  947. touch($src . "/bar.txt");
  948. touch($src . "/pic.png");
  949. $path = new Path($src);
  950. $results = [];
  951. foreach ($path->glob('*.txt') as $filename) {
  952. $results[] = (string)$filename;
  953. }
  954. $this->assertEquals(
  955. ['bar.txt', 'foo.txt'],
  956. $results
  957. );
  958. }
  959. }