PathTest.php 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997
  1. <?php
  2. namespace Path\Tests\unit;
  3. use Path\BuiltinProxy;
  4. use Path\Exception\FileExistsException;
  5. use Path\Exception\FileNotFoundException;
  6. use Path\Exception\IOException;
  7. use Path\Path;
  8. use PHPUnit\Framework\MockObject\MockObject;
  9. use PHPUnit\Framework\TestCase;
  10. class TestablePath extends Path {
  11. public function setBuiltin(BuiltinProxy $builtinProxy): void
  12. {
  13. $this->builtin = $builtinProxy;
  14. }
  15. public function cast(string|Path $path): Path
  16. {
  17. return parent::cast($path);
  18. }
  19. public function rrmdir(): bool {
  20. return $this->rrmdir();
  21. }
  22. }
  23. class PathTest extends TestCase
  24. {
  25. private BuiltinProxy | MockObject $builtin;
  26. public function setUp(): void
  27. {
  28. $this->builtin = $this->getMockBuilder(BuiltinProxy::class)->getMock();
  29. }
  30. public function getMock(string $path, string $methodName): TestablePath | MockObject
  31. {
  32. $mock = $this
  33. ->getMockBuilder(TestablePath::class)
  34. ->setConstructorArgs([$path])
  35. ->setMethodsExcept(['__toString', 'setBuiltin', $methodName])
  36. ->getMock();
  37. $mock->setBuiltin($this->builtin);
  38. return $mock;
  39. }
  40. /**
  41. * Test 'join' method.
  42. */
  43. public function testJoin(): void
  44. {
  45. // One part
  46. $this->assertEquals(
  47. '/home/user',
  48. Path::join('/home', 'user')
  49. );
  50. // Multiple parts
  51. $this->assertEquals(
  52. '/home/user/documents',
  53. Path::join('/home', 'user', 'documents')
  54. );
  55. // Absolute path passed in $parts
  56. $this->assertEquals(
  57. '/user/documents',
  58. Path::join('home', '/user', 'documents')
  59. );
  60. }
  61. public function testToString(): void
  62. {
  63. $path = new Path('/foo/bar');
  64. $this->assertEquals('/foo/bar', $path->__toString());
  65. }
  66. public function testPath()
  67. {
  68. $path = $this->getMock('bar', 'path');
  69. $this->assertEquals(
  70. 'bar',
  71. $path->path()
  72. );
  73. }
  74. public function testEq(): void
  75. {
  76. $path = $this->getMock('bar', 'eq');
  77. $path
  78. ->method('path')
  79. ->willReturn('bar');
  80. $path2 = $this->getMockBuilder(TestablePath::class)->disableOriginalConstructor()->getMock();
  81. $path2
  82. ->method('path')
  83. ->willReturn('bar');
  84. $path3 = $this->getMockBuilder(TestablePath::class)->disableOriginalConstructor()->getMock();
  85. $path3
  86. ->method('path')
  87. ->willReturn('/foo/bar');
  88. $path->method('cast')->willReturnMap(
  89. [
  90. [$path2, $path2],
  91. [$path3, $path3],
  92. ['bar', $path2],
  93. ['/foo/bar', $path3],
  94. ]
  95. );
  96. $this->assertTrue($path->eq($path2));
  97. $this->assertFalse($path->eq($path3));
  98. $this->assertTrue($path->eq('bar'));
  99. $this->assertFalse($path->eq('/foo/bar'));
  100. }
  101. /**
  102. * @throws IOException
  103. */
  104. public function testAbsPath(): void {
  105. $path = $this->getMock('bar', 'absPath');
  106. $this->builtin
  107. ->expects(self::once())
  108. ->method('realpath')
  109. ->with('bar')
  110. ->willReturn('/foo/bar');
  111. $newPath = $this->getMockBuilder(TestablePath::class)
  112. ->disableOriginalConstructor()
  113. ->getMock();
  114. $newPath->method('path')->willReturn('/foo/bar');
  115. $path->method('cast')->with('/foo/bar')->willReturn($newPath);
  116. $this->assertEquals(
  117. '/foo/bar',
  118. $path->absPath()->path()
  119. );
  120. }
  121. /**
  122. * @throws IOException
  123. */
  124. public function testRealPath()
  125. {
  126. $path = $this->getMock('bar', 'realpath');
  127. $newPath = $this->getMockBuilder(TestablePath::class)->disableOriginalConstructor()->getMock();
  128. $newPath
  129. ->method('eq')
  130. ->with('/foo/bar')
  131. ->willReturn(True);
  132. $path
  133. ->expects(self::once())
  134. ->method('absPath')
  135. ->willReturn($newPath);
  136. $this->assertTrue(
  137. $path->realpath()->eq('/foo/bar')
  138. );
  139. }
  140. public function testAccessFileExist(): void
  141. {
  142. $path = $this->getMock('bar', 'access');
  143. $this->builtin
  144. ->expects(self::once())
  145. ->method('file_exists')
  146. ->with('bar')
  147. ->willReturn(true);
  148. $this->builtin
  149. ->expects(self::never())
  150. ->method('is_readable')
  151. ->with('bar')
  152. ->willReturn(true);
  153. $this->builtin
  154. ->expects(self::never())
  155. ->method('is_writable')
  156. ->with('bar')
  157. ->willReturn(true);
  158. $this->builtin
  159. ->expects(self::never())
  160. ->method('is_executable')
  161. ->with('bar')
  162. ->willReturn(true);
  163. $this->assertTrue(
  164. $path->access(Path::F_OK)
  165. );
  166. }
  167. public function testAccessIsReadable(): void
  168. {
  169. $path = $this->getMock('bar', 'access');
  170. $this->builtin
  171. ->expects(self::never())
  172. ->method('file_exists')
  173. ->with('bar')
  174. ->willReturn(true);
  175. $this->builtin
  176. ->expects(self::once())
  177. ->method('is_readable')
  178. ->with('bar')
  179. ->willReturn(true);
  180. $this->builtin
  181. ->expects(self::never())
  182. ->method('is_writable')
  183. ->with('bar')
  184. ->willReturn(true);
  185. $this->builtin
  186. ->expects(self::never())
  187. ->method('is_executable')
  188. ->with('bar')
  189. ->willReturn(true);
  190. $this->assertTrue(
  191. $path->access(Path::R_OK)
  192. );
  193. }
  194. public function testAccessIsWritable(): void
  195. {
  196. $path = $this->getMock('bar', 'access');
  197. $this->builtin
  198. ->expects(self::never())
  199. ->method('file_exists')
  200. ->with('bar')
  201. ->willReturn(true);
  202. $this->builtin
  203. ->expects(self::never())
  204. ->method('is_readable')
  205. ->with('bar')
  206. ->willReturn(true);
  207. $this->builtin
  208. ->expects(self::once())
  209. ->method('is_writable')
  210. ->with('bar')
  211. ->willReturn(true);
  212. $this->builtin
  213. ->expects(self::never())
  214. ->method('is_executable')
  215. ->with('bar')
  216. ->willReturn(true);
  217. $this->assertTrue(
  218. $path->access(Path::W_OK)
  219. );
  220. }
  221. public function testAccessIsExecutable(): void
  222. {
  223. $path = $this->getMock('bar', 'access');
  224. $this->builtin
  225. ->expects(self::never())
  226. ->method('file_exists')
  227. ->with('bar')
  228. ->willReturn(true);
  229. $this->builtin
  230. ->expects(self::never())
  231. ->method('is_readable')
  232. ->with('bar')
  233. ->willReturn(true);
  234. $this->builtin
  235. ->expects(self::never())
  236. ->method('is_writable')
  237. ->with('bar')
  238. ->willReturn(true);
  239. $this->builtin
  240. ->expects(self::once())
  241. ->method('is_executable')
  242. ->with('bar')
  243. ->willReturn(true);
  244. $this->assertTrue(
  245. $path->access(Path::X_OK)
  246. );
  247. }
  248. public function testAccessInvalidMode(): void
  249. {
  250. $path = $this->getMock('bar', 'access');
  251. $this->builtin
  252. ->expects(self::never())
  253. ->method('file_exists')
  254. ->with('bar')
  255. ->willReturn(true);
  256. $this->builtin
  257. ->expects(self::never())
  258. ->method('is_readable')
  259. ->with('bar')
  260. ->willReturn(true);
  261. $this->builtin
  262. ->expects(self::never())
  263. ->method('is_writable')
  264. ->with('bar')
  265. ->willReturn(true);
  266. $this->builtin
  267. ->expects(self::never())
  268. ->method('is_executable')
  269. ->with('bar')
  270. ->willReturn(true);
  271. $this->expectException(\RuntimeException::class);
  272. $path->access(-1);
  273. }
  274. public function testATime(): void
  275. {
  276. $path = $this->getMock('bar', 'atime');
  277. $this->builtin
  278. ->expects(self::once())
  279. ->method('fileatime')
  280. ->with('bar')
  281. ->willReturn(1000);
  282. $date = '2000-01-01';
  283. $this->builtin
  284. ->expects(self::once())
  285. ->method('date')
  286. ->with('Y-m-d H:i:s', 1000)
  287. ->willReturn($date);
  288. $this->assertEquals(
  289. $date,
  290. $path->atime()
  291. );
  292. }
  293. public function testATimeError(): void
  294. {
  295. $path = $this->getMock('bar', 'atime');
  296. $this->builtin
  297. ->expects(self::once())
  298. ->method('fileatime')
  299. ->with('bar')
  300. ->willReturn(false);
  301. $this->assertEquals(
  302. null,
  303. $path->atime()
  304. );
  305. }
  306. public function testCTime(): void
  307. {
  308. $path = $this->getMock('bar', 'ctime');
  309. $this->builtin
  310. ->expects(self::once())
  311. ->method('filectime')
  312. ->with('bar')
  313. ->willReturn(1000);
  314. $date = '2000-01-01';
  315. $this->builtin
  316. ->expects(self::once())
  317. ->method('date')
  318. ->with('Y-m-d H:i:s', 1000)
  319. ->willReturn($date);
  320. $this->assertEquals(
  321. $date,
  322. $path->ctime()
  323. );
  324. }
  325. public function testCTimeError(): void
  326. {
  327. $path = $this->getMock('bar', 'ctime');
  328. $this->builtin
  329. ->expects(self::once())
  330. ->method('filectime')
  331. ->with('bar')
  332. ->willReturn(false);
  333. $this->assertEquals(
  334. null,
  335. $path->ctime()
  336. );
  337. }
  338. public function testMTime(): void
  339. {
  340. $path = $this->getMock('bar', 'mtime');
  341. $this->builtin
  342. ->expects(self::once())
  343. ->method('filemtime')
  344. ->with('bar')
  345. ->willReturn(1000);
  346. $date = '2000-01-01';
  347. $this->builtin
  348. ->expects(self::once())
  349. ->method('date')
  350. ->with('Y-m-d H:i:s', 1000)
  351. ->willReturn($date);
  352. $this->assertEquals(
  353. $date,
  354. $path->mtime()
  355. );
  356. }
  357. public function testMTimeError(): void
  358. {
  359. $path = $this->getMock('bar', 'mtime');
  360. $this->builtin
  361. ->expects(self::once())
  362. ->method('filemtime')
  363. ->with('bar')
  364. ->willReturn(false);
  365. $this->assertEquals(
  366. null,
  367. $path->mtime()
  368. );
  369. }
  370. public function testIsFile(): void
  371. {
  372. $path = $this->getMock('bar', 'isFile');
  373. $this->builtin
  374. ->expects(self::once())
  375. ->method('is_file')
  376. ->with('bar')
  377. ->willReturn(true);
  378. $this->assertTrue(
  379. $path->isFile()
  380. );
  381. }
  382. public function testIsDir(): void
  383. {
  384. $path = $this->getMock('bar', 'isDir');
  385. $this->builtin
  386. ->expects(self::once())
  387. ->method('is_dir')
  388. ->with('bar')
  389. ->willReturn(true);
  390. $this->assertTrue(
  391. $path->isDir()
  392. );
  393. }
  394. public function testExt(): void
  395. {
  396. $path = $this->getMock('bar.ext', 'ext');
  397. $this->builtin
  398. ->expects(self::once())
  399. ->method('pathinfo')
  400. ->with('bar.ext', PATHINFO_EXTENSION)
  401. ->willReturn('ext');
  402. $this->assertEquals(
  403. 'ext',
  404. $path->ext()
  405. );
  406. }
  407. public function testBaseName(): void
  408. {
  409. $path = $this->getMock('bar.ext', 'basename');
  410. $this->builtin
  411. ->expects(self::once())
  412. ->method('pathinfo')
  413. ->with('bar.ext', PATHINFO_BASENAME)
  414. ->willReturn('bar.ext');
  415. $this->assertEquals(
  416. 'bar.ext',
  417. $path->basename()
  418. );
  419. }
  420. public function testCD(): void
  421. {
  422. $path = $this->getMock('bar', 'cd');
  423. $this->builtin
  424. ->expects(self::once())
  425. ->method('chdir')
  426. ->with('foo')
  427. ->willReturn(true);
  428. $this->assertTrue(
  429. $path->cd('foo')
  430. );
  431. }
  432. public function testChDir(): void
  433. {
  434. $path = $this->getMock('bar', 'chdir');
  435. $path
  436. ->expects(self::once())
  437. ->method('cd')
  438. ->with('foo')
  439. ->willReturn(true);
  440. $this->assertTrue(
  441. $path->cd('foo')
  442. );
  443. }
  444. public function testName(): void
  445. {
  446. $path = $this->getMock('bar.ext', 'name');
  447. $this->builtin
  448. ->expects(self::once())
  449. ->method('pathinfo')
  450. ->with('bar.ext', PATHINFO_FILENAME)
  451. ->willReturn('bar');
  452. $this->assertEquals(
  453. 'bar',
  454. $path->name()
  455. );
  456. }
  457. /**
  458. * @throws IOException
  459. * @throws FileExistsException
  460. */
  461. public function testMkDir(): void
  462. {
  463. $path = $this->getMock('foo', 'mkdir');
  464. $path->method('isDir')->willReturn(False);
  465. $path->method('isFile')->willReturn(False);
  466. $this->builtin
  467. ->expects(self::once())
  468. ->method('mkdir')
  469. ->with('foo', 0777, false)
  470. ->willReturn(true);
  471. $path->mkdir();
  472. }
  473. /**
  474. * @throws IOException
  475. */
  476. public function testMkDirAlreadyExist(): void
  477. {
  478. $path = $this->getMock('foo', 'mkdir');
  479. $path->method('isDir')->willReturn(True);
  480. $this->expectException(FileExistsException::class);
  481. $path->mkdir();
  482. }
  483. /**
  484. * @throws IOException
  485. * @throws FileExistsException
  486. */
  487. public function testMkDirAlreadyExistButRecursive(): void
  488. {
  489. $path = $this->getMock('foo', 'mkdir');
  490. $path->method('isDir')->willReturn(True);
  491. $this->builtin
  492. ->expects(self::never())
  493. ->method('mkdir');
  494. $path->mkdir(0777, true);
  495. }
  496. /**
  497. * @throws IOException
  498. * @throws FileExistsException
  499. */
  500. public function testMkDirFileExists(): void
  501. {
  502. $path = $this->getMock('foo', 'mkdir');
  503. $path->method('isDir')->willReturn(False);
  504. $path->method('isFile')->willReturn(True);
  505. $this->expectException(FileExistsException::class);
  506. $path->mkdir();
  507. }
  508. /**
  509. * @throws IOException
  510. * @throws FileExistsException
  511. */
  512. public function testMkDirFileExistsButRecursive(): void
  513. {
  514. $path = $this->getMock('foo', 'mkdir');
  515. $path->method('isDir')->willReturn(False);
  516. $path->method('isFile')->willReturn(True);
  517. $this->expectException(FileExistsException::class);
  518. $path->mkdir(0777, true);
  519. }
  520. /**
  521. * @throws IOException
  522. * @throws FileExistsException
  523. */
  524. public function testMkDirIoError(): void
  525. {
  526. $path = $this->getMock('foo', 'mkdir');
  527. $path->method('isDir')->willReturn(False);
  528. $path->method('isFile')->willReturn(False);
  529. $this->builtin
  530. ->expects(self::once())
  531. ->method('mkdir')
  532. ->with('foo', 0777, false)
  533. ->willReturn(false);
  534. $this->expectException(IOException::class);
  535. $path->mkdir();
  536. }
  537. /**
  538. * @throws IOException
  539. * @throws FileNotFoundException
  540. */
  541. public function testDeleteIsFile(): void
  542. {
  543. $path = $this->getMock('foo', 'delete');
  544. $path->method('isFile')->willReturn(True);
  545. $path->method('isDir')->willReturn(False);
  546. $this->builtin
  547. ->expects(self::once())
  548. ->method('unlink')
  549. ->with('foo')
  550. ->willReturn(true);
  551. $path->delete();
  552. }
  553. /**
  554. * @throws IOException
  555. * @throws FileNotFoundException
  556. */
  557. public function testDeleteIsFileWithError(): void
  558. {
  559. $path = $this->getMock('foo', 'delete');
  560. $path->method('isFile')->willReturn(True);
  561. $path->method('isDir')->willReturn(False);
  562. $this->builtin
  563. ->expects(self::once())
  564. ->method('unlink')
  565. ->with('foo')
  566. ->willReturn(false);
  567. $this->expectException(IOException::class);
  568. $path->delete();
  569. }
  570. /**
  571. * @throws IOException
  572. * @throws FileNotFoundException
  573. */
  574. public function testDeleteIsDir(): void
  575. {
  576. $path = $this->getMock('foo', 'delete');
  577. $path->method('isFile')->willReturn(False);
  578. $path->method('isDir')->willReturn(True);
  579. $this->builtin
  580. ->expects(self::once())
  581. ->method('rmdir')
  582. ->with('foo')
  583. ->willReturn(true);
  584. $path->delete();
  585. }
  586. /**
  587. * @throws IOException
  588. * @throws FileNotFoundException
  589. */
  590. public function testDeleteIsDirWithError(): void
  591. {
  592. $path = $this->getMock('foo', 'delete');
  593. $path->method('isFile')->willReturn(False);
  594. $path->method('isDir')->willReturn(True);
  595. $this->builtin
  596. ->expects(self::once())
  597. ->method('rmdir')
  598. ->with('foo')
  599. ->willReturn(false);
  600. $this->expectException(IOException::class);
  601. $path->delete();
  602. }
  603. /**
  604. * @throws IOException
  605. * @throws FileNotFoundException
  606. */
  607. public function testDeleteNonExistentFile(): void
  608. {
  609. $path = $this->getMock('foo', 'delete');
  610. $path->method('isFile')->willReturn(False);
  611. $path->method('isDir')->willReturn(False);
  612. $this->builtin
  613. ->expects(self::never())
  614. ->method('unlink');
  615. $this->builtin
  616. ->expects(self::never())
  617. ->method('rmdir');
  618. $this->expectException(FileNotFoundException::class);
  619. $path->delete();
  620. }
  621. /**
  622. * @throws IOException
  623. * @throws FileNotFoundException
  624. * @throws FileExistsException
  625. */
  626. public function testCopy()
  627. {
  628. $path = $this->getMock('foo.ext', 'copy');
  629. $path->method('isFile')->willReturn(True);
  630. $destination = "/bar/foo2.ext";
  631. $this->builtin
  632. ->expects(self::once())
  633. ->method('is_dir')
  634. ->with($destination)
  635. ->willReturn(False);
  636. $this->builtin
  637. ->expects(self::once())
  638. ->method('file_exists')
  639. ->with($destination)
  640. ->willReturn(False);
  641. $this->builtin
  642. ->expects(self::once())
  643. ->method('copy')
  644. ->with('foo.ext', $destination)
  645. ->willReturn(True);
  646. $newPath = $this->getMockBuilder(TestablePath::class)->disableOriginalConstructor()->getMock();
  647. $newPath->method('eq')->with($destination)->willReturn(True);
  648. $path->method('cast')->with($destination)->willReturn($newPath);
  649. $result = $path->copy($destination);
  650. $this->assertTrue(
  651. $result->eq($destination)
  652. );
  653. }
  654. /**
  655. * @throws IOException
  656. * @throws FileNotFoundException
  657. * @throws FileExistsException
  658. */
  659. public function testCopyFileDoesNotExist()
  660. {
  661. $path = $this->getMock('foo.ext', 'copy');
  662. $path->method('isFile')->willReturn(False);
  663. $destination = "/bar/foo2.ext";
  664. $this->builtin
  665. ->expects(self::never())
  666. ->method('is_dir');
  667. $this->builtin
  668. ->expects(self::never())
  669. ->method('file_exists');
  670. $this->builtin
  671. ->expects(self::never())
  672. ->method('copy');
  673. $this->expectException(FileNotFoundException::class);
  674. $path->copy($destination);
  675. }
  676. /**
  677. * @throws IOException
  678. * @throws FileNotFoundException
  679. * @throws FileExistsException
  680. */
  681. public function testCopyDestIsDir()
  682. {
  683. $path = $this->getMock('foo.ext', 'copy');
  684. $path->method('isFile')->willReturn(True);
  685. $path->method('basename')->willReturn('foo.ext');
  686. $destination = "/bar";
  687. $this->builtin
  688. ->expects(self::once())
  689. ->method('is_dir')
  690. ->with($destination)
  691. ->willReturn(True);
  692. $newDest = $destination . "/foo.ext";
  693. $this->builtin
  694. ->expects(self::once())
  695. ->method('file_exists')
  696. ->with($newDest)
  697. ->willReturn(False);
  698. $this->builtin
  699. ->expects(self::once())
  700. ->method('copy')
  701. ->with('foo.ext', $newDest)
  702. ->willReturn(True);
  703. $newPath = $this->getMockBuilder(TestablePath::class)->disableOriginalConstructor()->getMock();
  704. $newPath->method('eq')->with($newDest)->willReturn(True);
  705. $path->method('cast')->with($newDest)->willReturn($newPath);
  706. $result = $path->copy($destination);
  707. $this->assertTrue(
  708. $result->eq($newDest)
  709. );
  710. }
  711. /**
  712. * @throws IOException
  713. * @throws FileNotFoundException
  714. * @throws FileExistsException
  715. */
  716. public function testCopyFileAlreadyExists()
  717. {
  718. $path = $this->getMock('foo.ext', 'copy');
  719. $path->method('isFile')->willReturn(True);
  720. $destination = "/bar/foo2.ext";
  721. $this->builtin
  722. ->expects(self::once())
  723. ->method('is_dir')
  724. ->with($destination)
  725. ->willReturn(False);
  726. $this->builtin
  727. ->expects(self::once())
  728. ->method('file_exists')
  729. ->with($destination)
  730. ->willReturn(True);
  731. $this->builtin
  732. ->expects(self::never())
  733. ->method('copy');
  734. $this->expectException(FileExistsException::class);
  735. $path->copy($destination);
  736. }
  737. /**
  738. * @throws IOException
  739. * @throws FileNotFoundException
  740. * @throws FileExistsException
  741. */
  742. public function testCopyFileDestIsDirButFileAlreadyExists()
  743. {
  744. $path = $this->getMock('foo.ext', 'copy');
  745. $path->method('isFile')->willReturn(True);
  746. $path->method('basename')->willReturn('foo.ext');
  747. $destination = "/bar";
  748. $this->builtin
  749. ->expects(self::once())
  750. ->method('is_dir')
  751. ->with($destination)
  752. ->willReturn(True);
  753. $newDest = $destination . "/foo.ext";
  754. $this->builtin
  755. ->expects(self::once())
  756. ->method('file_exists')
  757. ->with($newDest)
  758. ->willReturn(True);
  759. $this->builtin
  760. ->expects(self::never())
  761. ->method('copy');
  762. $this->expectException(FileExistsException::class);
  763. $path->copy($destination);
  764. }
  765. /**
  766. * @throws IOException
  767. * @throws FileNotFoundException
  768. * @throws FileExistsException
  769. */
  770. public function testCopyFileWithError()
  771. {
  772. $path = $this->getMock('foo.ext', 'copy');
  773. $path->method('isFile')->willReturn(True);
  774. $destination = "/bar/foo2.ext";
  775. $this->builtin
  776. ->expects(self::once())
  777. ->method('is_dir')
  778. ->with($destination)
  779. ->willReturn(False);
  780. $this->builtin
  781. ->expects(self::once())
  782. ->method('file_exists')
  783. ->with($destination)
  784. ->willReturn(False);
  785. $this->builtin
  786. ->expects(self::once())
  787. ->method('copy')
  788. ->with('foo.ext', $destination)
  789. ->willReturn(False);
  790. $this->expectException(IOException::class);
  791. $path->copy($destination);
  792. }
  793. // public function testCopyTree(): void {
  794. // TODO: implement
  795. // }
  796. /**
  797. * @throws IOException
  798. * @throws FileExistsException
  799. */
  800. public function testMove()
  801. {
  802. $path = $this->getMock('foo.ext', 'move');
  803. $destination = "/bar/foo2.ext";
  804. $this->builtin
  805. ->expects(self::once())
  806. ->method('is_dir')
  807. ->with($destination)
  808. ->willReturn(False);
  809. $this->builtin
  810. ->expects(self::once())
  811. ->method('file_exists')
  812. ->with($destination)
  813. ->willReturn(False);
  814. $this->builtin
  815. ->expects(self::once())
  816. ->method('rename')
  817. ->with('foo.ext', $destination)
  818. ->willReturn(True);
  819. $destinationPath = $this->getMockBuilder(TestablePath::class)->disableOriginalConstructor()->getMock();
  820. $destinationPath->method('eq')->with($destination)->willReturn(True);
  821. $path->method('cast')->with($destination)->willReturn($destinationPath);
  822. $result = $path->move($destination);
  823. $this->assertTrue(
  824. $result->eq($destination)
  825. );
  826. }
  827. /**
  828. * @throws IOException
  829. * @throws FileExistsException
  830. */
  831. public function testMoveWithPath()
  832. {
  833. $path = $this->getMock('foo.ext', 'move');
  834. $destination = new Path("/bar/foo2.ext");
  835. $this->builtin
  836. ->expects(self::once())
  837. ->method('is_dir')
  838. ->with($destination)
  839. ->willReturn(False);
  840. $this->builtin
  841. ->expects(self::once())
  842. ->method('file_exists')
  843. ->with($destination)
  844. ->willReturn(False);
  845. $this->builtin
  846. ->expects(self::once())
  847. ->method('rename')
  848. ->with('foo.ext', $destination)
  849. ->willReturn(True);
  850. $destinationPath = $this->getMockBuilder(TestablePath::class)->disableOriginalConstructor()->getMock();
  851. $destinationPath->method('eq')->with($destination)->willReturn(True);
  852. $path->method('cast')->with($destination)->willReturn($destinationPath);
  853. $result = $path->move($destination);
  854. $this->assertTrue(
  855. $result->eq($destination)
  856. );
  857. }
  858. /**
  859. * @throws IOException
  860. * @throws FileExistsException
  861. */
  862. public function testMoveDestIsDir()
  863. {
  864. $path = $this->getMock('foo.ext', 'move');
  865. $path->method('basename')->willReturn('foo.ext');
  866. $destination = "/bar";
  867. $this->builtin
  868. ->expects(self::once())
  869. ->method('is_dir')
  870. ->with($destination)
  871. ->willReturn(True);
  872. $newDestination = $destination . "/foo.ext";
  873. $this->builtin
  874. ->expects(self::once())
  875. ->method('file_exists')
  876. ->with($newDestination)
  877. ->willReturn(False);
  878. $this->builtin
  879. ->expects(self::once())
  880. ->method('rename')
  881. ->with('foo.ext', $newDestination)
  882. ->willReturn(True);
  883. $destinationPath = $this->getMockBuilder(TestablePath::class)->disableOriginalConstructor()->getMock();
  884. $destinationPath->method('eq')->with($newDestination)->willReturn(True);
  885. $path->method('cast')->with($newDestination)->willReturn($destinationPath);
  886. $result = $path->move($destination);
  887. $this->assertTrue(
  888. $result->eq($newDestination)
  889. );
  890. }
  891. /**
  892. * @throws IOException
  893. * @throws FileExistsException
  894. */
  895. public function testMoveFileExist()
  896. {
  897. $path = $this->getMock('foo.ext', 'move');
  898. $path->method('basename')->willReturn('foo.ext');
  899. $destination = "/bar/foo2.ext";
  900. $this->builtin
  901. ->expects(self::once())
  902. ->method('is_dir')
  903. ->with($destination)
  904. ->willReturn(False);
  905. $this->builtin
  906. ->expects(self::once())
  907. ->method('file_exists')
  908. ->with($destination)
  909. ->willReturn(True);
  910. $this->builtin
  911. ->expects(self::never())
  912. ->method('rename');
  913. $this->expectException(FileExistsException::class);
  914. $path->move($destination);
  915. }
  916. /**
  917. * @throws IOException
  918. * @throws FileExistsException
  919. */
  920. public function testMoveWithError()
  921. {
  922. $path = $this->getMock('foo.ext', 'move');
  923. $path->method('basename')->willReturn('foo.ext');
  924. $destination = "/bar/foo2.ext";
  925. $this->builtin
  926. ->expects(self::once())
  927. ->method('is_dir')
  928. ->with($destination)
  929. ->willReturn(False);
  930. $this->builtin
  931. ->expects(self::once())
  932. ->method('file_exists')
  933. ->with($destination)
  934. ->willReturn(False);
  935. $this->builtin
  936. ->expects(self::once())
  937. ->method('rename')
  938. ->with('foo.ext', $destination)
  939. ->willReturn(False);
  940. $this->expectException(IOException::class);
  941. $path->move($destination);
  942. }
  943. /**
  944. * @throws IOException
  945. */
  946. public function testTouchWithNoTimestamps()
  947. {
  948. $path = $this->getMock('foo.ext', 'touch');
  949. $this->builtin
  950. ->expects(self::once())
  951. ->method('touch')
  952. ->with('foo.ext', null, null)
  953. ->willReturn(True);
  954. $path->touch();
  955. }
  956. /**
  957. * @throws IOException
  958. */
  959. public function testTouchWithTimestamps()
  960. {
  961. $path = $this->getMock('foo.ext', 'touch');
  962. $this->builtin
  963. ->expects(self::once())
  964. ->method('touch')
  965. ->with('foo.ext', 123, 456)
  966. ->willReturn(True);
  967. $path->touch(123, 456);
  968. }
  969. /**
  970. * @throws IOException
  971. */
  972. public function testTouchWithDatetimes()
  973. {
  974. $path = $this->getMock('foo.ext', 'touch');
  975. $datetime1 = $this->getMockBuilder(\DateTime::class)->getMock();
  976. $datetime1->method('getTimestamp')->willReturn(123);
  977. $datetime2 = $this->getMockBuilder(\DateTime::class)->getMock();
  978. $datetime2->method('getTimestamp')->willReturn(456);
  979. $this->builtin
  980. ->expects(self::once())
  981. ->method('touch')
  982. ->with('foo.ext', 123, 456)
  983. ->willReturn(True);
  984. $path->touch($datetime1, $datetime2);
  985. }
  986. /**
  987. * @throws IOException
  988. */
  989. public function testTouchWithError()
  990. {
  991. $path = $this->getMock('foo.ext', 'touch');
  992. $this->builtin
  993. ->expects(self::once())
  994. ->method('touch')
  995. ->with('foo.ext')
  996. ->willReturn(False);
  997. $this->expectException(IOException::class);
  998. $path->touch();
  999. }
  1000. /**
  1001. * @throws IOException
  1002. * @throws FileNotFoundException
  1003. */
  1004. public function testSize()
  1005. {
  1006. $path = $this->getMock('foo.ext', 'size');
  1007. $path->method('isFile')->willReturn(True);
  1008. $this->builtin
  1009. ->expects(self::once())
  1010. ->method('filesize')
  1011. ->with('foo.ext')
  1012. ->willReturn(123456);
  1013. $this->assertEquals(
  1014. 123456,
  1015. $path->size()
  1016. );
  1017. }
  1018. /**
  1019. * @throws IOException
  1020. * @throws FileNotFoundException
  1021. */
  1022. public function testSizeFileNotExist()
  1023. {
  1024. $path = $this->getMock('foo.ext', 'size');
  1025. $path->method('isFile')->willReturn(False);
  1026. $this->builtin
  1027. ->expects(self::never())
  1028. ->method('filesize');
  1029. $this->expectException(FileNotFoundException::class);
  1030. $path->size();
  1031. }
  1032. /**
  1033. * @throws IOException
  1034. * @throws FileNotFoundException
  1035. */
  1036. public function testSizeFileWithError()
  1037. {
  1038. $path = $this->getMock('foo.ext', 'size');
  1039. $path->method('isFile')->willReturn(True);
  1040. $this->builtin
  1041. ->expects(self::once())
  1042. ->method('filesize')
  1043. ->with('foo.ext')
  1044. ->willReturn(False);
  1045. $this->expectException(IOException::class);
  1046. $path->size();
  1047. }
  1048. public function testParent(): void
  1049. {
  1050. $path = $this->getMock('/foo/foo.ext', 'parent');
  1051. $this->builtin
  1052. ->expects(self::once())
  1053. ->method('dirname')
  1054. ->with('/foo/foo.ext')
  1055. ->willReturn('/foo');
  1056. $newPath = $this->getMockBuilder(TestablePath::class)->disableOriginalConstructor()->getMock();
  1057. $path->method('cast')->with('/foo')->willReturn($newPath);
  1058. $newPath->method('eq')->with('/foo')->willReturn(True);
  1059. $this->assertTrue(
  1060. $path->parent()->eq('/foo')
  1061. );
  1062. }
  1063. public function testDirName(): void
  1064. {
  1065. $path = $this->getMock('/foo/foo.ext', 'dirname');
  1066. $newPath = $this->getMockBuilder(TestablePath::class)->disableOriginalConstructor()->getMock();
  1067. $newPath->method('eq')->with('/foo')->willReturn(True);
  1068. $path
  1069. ->expects(self::once())
  1070. ->method('parent')
  1071. ->willReturn($newPath);
  1072. $this->assertTrue(
  1073. $path->dirname()->eq('/foo')
  1074. );
  1075. }
  1076. /**
  1077. * @throws FileNotFoundException
  1078. */
  1079. public function testDirs()
  1080. {
  1081. $path = $this->getMock('/foo', 'dirs');
  1082. $this->builtin
  1083. ->method('is_dir')
  1084. ->willReturnMap(
  1085. [
  1086. ['/foo', True],
  1087. ['/foo/file.ext', False],
  1088. ['/foo/dir1', True],
  1089. ['/foo/dir2', True],
  1090. ]
  1091. );
  1092. $results = [
  1093. '..',
  1094. '.',
  1095. 'file.ext',
  1096. 'dir1',
  1097. 'dir2'
  1098. ];
  1099. $this->builtin
  1100. ->expects(self::once())
  1101. ->method('scandir')
  1102. ->with('/foo')
  1103. ->willReturn($results);
  1104. $this->assertEquals(
  1105. ['dir1', 'dir2'],
  1106. $path->dirs()
  1107. );
  1108. }
  1109. /**
  1110. * @throws FileNotFoundException
  1111. */
  1112. public function testDirsIsNotDir()
  1113. {
  1114. $path = $this->getMock('/foo', 'dirs');
  1115. $this->builtin
  1116. ->method('is_dir')
  1117. ->with('/foo')
  1118. ->willReturn(False);
  1119. $this->expectException(FileNotFoundException::class);
  1120. $path->dirs();
  1121. }
  1122. /**
  1123. * @throws FileNotFoundException
  1124. */
  1125. public function testFiles()
  1126. {
  1127. $path = $this->getMock('/foo', 'files');
  1128. $this->builtin
  1129. ->method('is_dir')
  1130. ->with('/foo')
  1131. ->willReturn(True);
  1132. $this->builtin
  1133. ->method('is_file')
  1134. ->willReturnMap(
  1135. [
  1136. ['/foo/file1.ext', True],
  1137. ['/foo/file2.ext', True],
  1138. ['/foo/dir1', False],
  1139. ]
  1140. );
  1141. $results = [
  1142. '..',
  1143. '.',
  1144. 'file1.ext',
  1145. 'file2.ext',
  1146. 'dir1'
  1147. ];
  1148. $this->builtin
  1149. ->expects(self::once())
  1150. ->method('scandir')
  1151. ->with('/foo')
  1152. ->willReturn($results);
  1153. $this->assertEquals(
  1154. ['file1.ext', 'file2.ext'],
  1155. $path->files()
  1156. );
  1157. }
  1158. /**
  1159. * @throws FileNotFoundException
  1160. */
  1161. public function testFilesIsNotDir()
  1162. {
  1163. $path = $this->getMock('/foo', 'files');
  1164. $this->builtin
  1165. ->method('is_dir')
  1166. ->with('/foo')
  1167. ->willReturn(False);
  1168. $this->expectException(FileNotFoundException::class);
  1169. $path->files();
  1170. }
  1171. // public function testFnMatch(): void
  1172. // {
  1173. // //TODO: implements
  1174. // }
  1175. /**
  1176. * @throws IOException
  1177. * @throws FileNotFoundException
  1178. */
  1179. public function testGetContent(): void
  1180. {
  1181. $path = $this->getMock('/foo/file.ext', 'getContent');
  1182. $this->builtin
  1183. ->method('is_file')
  1184. ->with('/foo/file.ext')
  1185. ->willReturn(True);
  1186. $this->builtin
  1187. ->method('file_get_contents')
  1188. ->with('/foo/file.ext')
  1189. ->willReturn('azerty');
  1190. $this->assertEquals(
  1191. 'azerty',
  1192. $path->getContent()
  1193. );
  1194. }
  1195. /**
  1196. * @throws IOException
  1197. * @throws FileNotFoundException
  1198. */
  1199. public function testGetContentFileDoesNotExist(): void
  1200. {
  1201. $path = $this->getMock('/foo/file.ext', 'getContent');
  1202. $this->builtin
  1203. ->method('is_file')
  1204. ->with('/foo/file.ext')
  1205. ->willReturn(False);
  1206. $this->builtin
  1207. ->expects(self::never())
  1208. ->method('file_get_contents');
  1209. $this->expectException(FileNotFoundException::class);
  1210. $path->getContent();
  1211. }
  1212. /**
  1213. * @throws IOException
  1214. * @throws FileNotFoundException
  1215. */
  1216. public function testGetContentErrorWhileReading(): void
  1217. {
  1218. $path = $this->getMock('/foo/file.ext', 'getContent');
  1219. $this->builtin
  1220. ->method('is_file')
  1221. ->with('/foo/file.ext')
  1222. ->willReturn(True);
  1223. $this->builtin
  1224. ->method('file_get_contents')
  1225. ->with('/foo/file.ext')
  1226. ->willReturn(False);
  1227. $this->expectException(IOException::class);
  1228. $path->getContent();
  1229. }
  1230. /**
  1231. * @throws IOException
  1232. * @throws FileNotFoundException
  1233. */
  1234. public function testPutContent(): void
  1235. {
  1236. $path = $this->getMock('/foo/file.ext', 'putContent');
  1237. $this->builtin
  1238. ->method('is_file')
  1239. ->with('/foo/file.ext')
  1240. ->willReturn(True);
  1241. $this->builtin
  1242. ->expects(self::once())
  1243. ->method('file_put_contents')
  1244. ->with('/foo/file.ext', 'azerty')
  1245. ->willReturn(6);
  1246. $this->assertEquals(
  1247. 6,
  1248. $path->putContent('azerty')
  1249. );
  1250. }
  1251. /**
  1252. * @throws IOException
  1253. * @throws FileNotFoundException
  1254. */
  1255. public function testPutContentAndAppend(): void
  1256. {
  1257. $path = $this->getMock('/foo/file.ext', 'putContent');
  1258. $this->builtin
  1259. ->method('is_file')
  1260. ->with('/foo/file.ext')
  1261. ->willReturn(True);
  1262. $this->builtin
  1263. ->expects(self::once())
  1264. ->method('file_put_contents')
  1265. ->with('/foo/file.ext', 'azerty', FILE_APPEND)
  1266. ->willReturn(6);
  1267. $this->assertEquals(
  1268. 6,
  1269. $path->putContent('azerty', True)
  1270. );
  1271. }
  1272. /**
  1273. * @throws IOException
  1274. * @throws FileNotFoundException
  1275. */
  1276. public function testPutContentFileDoesNotExist(): void
  1277. {
  1278. $path = $this->getMock('/foo/file.ext', 'putContent');
  1279. $this->builtin
  1280. ->method('is_file')
  1281. ->with('/foo/file.ext')
  1282. ->willReturn(False);
  1283. $this->builtin
  1284. ->expects(self::never())
  1285. ->method('file_put_contents');
  1286. $this->expectException(FileNotFoundException::class);
  1287. $path->putContent('azerty');
  1288. }
  1289. /**
  1290. * @throws IOException
  1291. * @throws FileNotFoundException
  1292. */
  1293. public function testPutContentErrorWhileWriting(): void
  1294. {
  1295. $path = $this->getMock('/foo/file.ext', 'putContent');
  1296. $this->builtin
  1297. ->method('is_file')
  1298. ->with('/foo/file.ext')
  1299. ->willReturn(True);
  1300. $this->builtin
  1301. ->method('file_put_contents')
  1302. ->with('/foo/file.ext')
  1303. ->willReturn(False);
  1304. $this->expectException(IOException::class);
  1305. $path->putContent('azerty');
  1306. }
  1307. /**
  1308. * @throws IOException
  1309. * @throws FileNotFoundException
  1310. */
  1311. public function testPutLines(): void
  1312. {
  1313. $path = $this->getMock('/foo/file.ext', 'putLines');
  1314. $lines = [
  1315. 'once upon a time',
  1316. 'a man and a spoon',
  1317. 'had a great time drinking coffee'
  1318. ];
  1319. $path
  1320. ->expects(self::once())
  1321. ->method('putContent')
  1322. ->with(implode(PHP_EOL, $lines))
  1323. ->willReturn(123);
  1324. $this->assertEquals(
  1325. 123,
  1326. $path->putLines($lines)
  1327. );
  1328. }
  1329. /**
  1330. * @throws IOException
  1331. * @throws FileNotFoundException
  1332. */
  1333. public function testGetPermissions(): void
  1334. {
  1335. $path = $this->getMock('/foo/file.ext', 'getPermissions');
  1336. $path->method('isFile')->willReturn(True);
  1337. $this->builtin
  1338. ->method('fileperms')
  1339. ->with('/foo/file.ext')
  1340. ->willReturn(16895);
  1341. $this->assertEquals(
  1342. 777,
  1343. $path->getPermissions()
  1344. );
  1345. }
  1346. /**
  1347. * @throws IOException
  1348. * @throws FileNotFoundException
  1349. */
  1350. public function testGetPermissionsFileDoesNotExist(): void
  1351. {
  1352. $path = $this->getMock('/foo/file.ext', 'getPermissions');
  1353. $path->method('isFile')->willReturn(False);
  1354. $this->builtin
  1355. ->expects(self::never())
  1356. ->method('fileperms');
  1357. $this->expectException(FileNotFoundException::class);
  1358. $path->getPermissions();
  1359. }
  1360. /**
  1361. * @throws IOException
  1362. * @throws FileNotFoundException
  1363. */
  1364. public function testGetPermissionsWithError(): void
  1365. {
  1366. $path = $this->getMock('/foo/file.ext', 'getPermissions');
  1367. $path->method('isFile')->willReturn(True);
  1368. $this->builtin
  1369. ->method('fileperms')
  1370. ->with('/foo/file.ext')
  1371. ->willReturn(False);
  1372. $this->expectException(IOException::class);
  1373. $path->getPermissions();
  1374. }
  1375. /**
  1376. * @throws FileNotFoundException|IOException
  1377. */
  1378. public function testSetPermissions(): void
  1379. {
  1380. $path = $this->getMock('/foo/file.ext', 'setPermissions');
  1381. $path->method('isFile')->willReturn(True);
  1382. $this->builtin
  1383. ->method('chmod')
  1384. ->with('/foo/file.ext', 0777)
  1385. ->willReturn(True);
  1386. $this->builtin
  1387. ->expects(self::once())
  1388. ->method('clearstatcache');
  1389. $this->assertTrue(
  1390. $path->setPermissions(0777)
  1391. );
  1392. }
  1393. /**
  1394. * @throws FileNotFoundException|IOException
  1395. */
  1396. public function testSetPermissionsFileDoesNotExist(): void
  1397. {
  1398. $path = $this->getMock('/foo/file.ext', 'setPermissions');
  1399. $path->method('isFile')->willReturn(False);
  1400. $this->builtin
  1401. ->expects(self::never())
  1402. ->method('clearstatcache');
  1403. $this->builtin
  1404. ->expects(self::never())
  1405. ->method('chmod');
  1406. $this->expectException(FileNotFoundException::class);
  1407. $path->setPermissions(0777);
  1408. }
  1409. /**
  1410. * @throws FileNotFoundException
  1411. */
  1412. public function testSetPermissionsWithError(): void
  1413. {
  1414. $path = $this->getMock('/foo/file.ext', 'setPermissions');
  1415. $path->method('isFile')->willReturn(True);
  1416. $this->builtin
  1417. ->expects(self::once())
  1418. ->method('clearstatcache');
  1419. $this->builtin
  1420. ->method('chmod')
  1421. ->with('/foo/file.ext', 0777)
  1422. ->willReturn(False);
  1423. $this->expectException(IOException::class);
  1424. $path->setPermissions(0777);
  1425. }
  1426. /**
  1427. * @throws FileNotFoundException
  1428. */
  1429. public function testSetOwner(): void
  1430. {
  1431. $path = $this->getMock('/foo/file.ext', 'setOwner');
  1432. $path->method('isFile')->willReturn(True);
  1433. $this->builtin
  1434. ->expects(self::once())
  1435. ->method('clearstatcache');
  1436. $this->builtin
  1437. ->method('chown')
  1438. ->with('/foo/file.ext', 'user')
  1439. ->willReturn(True);
  1440. $this->builtin
  1441. ->method('chgrp')
  1442. ->with('/foo/file.ext', 'group')
  1443. ->willReturn(True);
  1444. $path->setOwner('user', 'group');
  1445. }
  1446. /**
  1447. * @throws FileNotFoundException|IOException
  1448. */
  1449. public function testSetOwnerFileDoesNotExist(): void
  1450. {
  1451. $path = $this->getMock('/foo/file.ext', 'setOwner');
  1452. $path->method('isFile')->willReturn(False);
  1453. $this->builtin
  1454. ->expects(self::never())
  1455. ->method('clearstatcache');
  1456. $this->builtin
  1457. ->expects(self::never())
  1458. ->method('chown');
  1459. $this->builtin
  1460. ->expects(self::never())
  1461. ->method('chgrp');
  1462. $this->expectException(FileNotFoundException::class);
  1463. $path->setOwner('user', 'group');
  1464. }
  1465. /**
  1466. * @throws FileNotFoundException
  1467. */
  1468. public function testSetPermissionsWithChownError(): void
  1469. {
  1470. $path = $this->getMock('/foo/file.ext', 'setOwner');
  1471. $path->method('isFile')->willReturn(True);
  1472. $this->builtin
  1473. ->expects(self::once())
  1474. ->method('clearstatcache');
  1475. $this->builtin
  1476. ->method('chown')
  1477. ->with('/foo/file.ext', 'user')
  1478. ->willReturn(False);
  1479. $this->builtin
  1480. ->method('chgrp')
  1481. ->with('/foo/file.ext', 'group')
  1482. ->willReturn(True);
  1483. $this->expectException(IOException::class);
  1484. $path->setOwner('user', 'group');
  1485. }
  1486. /**
  1487. * @throws FileNotFoundException
  1488. */
  1489. public function testSetPermissionsWithChGroupError(): void
  1490. {
  1491. $path = $this->getMock('/foo/file.ext', 'setOwner');
  1492. $path->method('isFile')->willReturn(True);
  1493. $this->builtin
  1494. ->method('chown')
  1495. ->with('/foo/file.ext', 'user')
  1496. ->willReturn(True);
  1497. $this->builtin
  1498. ->method('chgrp')
  1499. ->with('/foo/file.ext', 'group')
  1500. ->willReturn(False);
  1501. $this->expectException(IOException::class);
  1502. $path->setOwner('user', 'group');
  1503. }
  1504. public function testExists(): void
  1505. {
  1506. $path = $this->getMock('/foo/file.ext', 'exists');
  1507. $this->builtin
  1508. ->expects(self::once())
  1509. ->method('file_exists')
  1510. ->with('/foo/file.ext')
  1511. ->willReturn(True);
  1512. $this->assertTrue(
  1513. $path->exists()
  1514. );
  1515. }
  1516. /**
  1517. * @throws IOException
  1518. * @throws FileNotFoundException
  1519. */
  1520. public function testGlob(): void {
  1521. $path = $this->getMock('/foo', 'glob');
  1522. $path->method('isDir')->willReturn(True);
  1523. $this->builtin
  1524. ->expects(self::once())
  1525. ->method('glob')
  1526. ->with('/foo/*')
  1527. ->willReturn(['a', 'b', 'c']);
  1528. $this->assertEquals(
  1529. ['a', 'b', 'c'],
  1530. array_map(
  1531. function (Path $p) { return (string)$p; },
  1532. $path->glob('*')
  1533. )
  1534. );
  1535. }
  1536. /**
  1537. * @throws IOException
  1538. */
  1539. public function testGlobDirDoesNotExist(): void {
  1540. $path = $this->getMock('/foo', 'glob');
  1541. $path->method('isDir')->willReturn(False);
  1542. $this->builtin
  1543. ->expects(self::never())
  1544. ->method('glob');
  1545. $this->expectException(FileNotFoundException::class);
  1546. $path->glob('*');
  1547. }
  1548. /**
  1549. * @throws FileNotFoundException
  1550. */
  1551. public function testGlobWithError(): void {
  1552. $path = $this->getMock('/foo', 'glob');
  1553. $path->method('isDir')->willReturn(True);
  1554. $this->builtin
  1555. ->expects(self::once())
  1556. ->method('glob')
  1557. ->with('/foo/*')
  1558. ->willReturn(False);
  1559. $this->expectException(IOException::class);
  1560. $path->glob('*');
  1561. }
  1562. /**
  1563. * @throws FileNotFoundException
  1564. * @throws IOException
  1565. */
  1566. public function testRmDirNonRecursive(): void
  1567. {
  1568. $path = $this->getMock('/foo', 'rmdir');
  1569. $path->method('isDir')->willReturn(True);
  1570. $this->builtin
  1571. ->method('rmdir')
  1572. ->with('/foo')
  1573. ->willReturn(True);
  1574. $path
  1575. ->expects(self::never())
  1576. ->method('rrmdir');
  1577. $path->rmdir();
  1578. }
  1579. /**
  1580. * @throws FileNotFoundException
  1581. * @throws IOException
  1582. */
  1583. public function testRmDirRecursive(): void
  1584. {
  1585. $path = $this->getMock('/foo', 'rmdir');
  1586. $path->method('isDir')->willReturn(True);
  1587. $this->builtin
  1588. ->expects(self::never())
  1589. ->method('rmdir');
  1590. $path
  1591. ->method('rrmdir')
  1592. ->willReturn(True);
  1593. $path->rmdir(True);
  1594. }
  1595. }