Wrapper.php 28KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911
  1. <?php
  2. /**
  3. * Hoa
  4. *
  5. *
  6. * @license
  7. *
  8. * New BSD License
  9. *
  10. * Copyright © 2007-2017, Hoa community. All rights reserved.
  11. *
  12. * Redistribution and use in source and binary forms, with or without
  13. * modification, are permitted provided that the following conditions are met:
  14. * * Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. * * Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in the
  18. * documentation and/or other materials provided with the distribution.
  19. * * Neither the name of the Hoa nor the names of its contributors may be
  20. * used to endorse or promote products derived from this software without
  21. * specific prior written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  24. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
  27. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  28. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  29. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  30. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  31. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  32. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33. * POSSIBILITY OF SUCH DAMAGE.
  34. */
  35. namespace Hoa\Protocol\Test\Unit;
  36. use Hoa\Protocol as LUT;
  37. use Hoa\Protocol\Wrapper as SUT;
  38. use Hoa\Test;
  39. /**
  40. * Class \Hoa\Protocol\Test\Unit\Wrapper.
  41. *
  42. * Test suite of the stream wrapper.
  43. *
  44. * @copyright Copyright © 2007-2017 Hoa community
  45. * @license New BSD License
  46. */
  47. class Wrapper extends Test\Unit\Suite
  48. {
  49. public function case_stream_cast_for_select()
  50. {
  51. $this
  52. ->given($wrapper = new SUT())
  53. ->when($result = $wrapper->stream_cast(STREAM_CAST_FOR_SELECT))
  54. ->then
  55. ->boolean($result)
  56. ->isFalse();
  57. }
  58. public function case_stream_cast_as_stream()
  59. {
  60. $this
  61. ->given($wrapper = new SUT())
  62. ->when($result = $wrapper->stream_cast(STREAM_CAST_AS_STREAM))
  63. ->then
  64. ->boolean($result)
  65. ->isFalse();
  66. }
  67. public function case_stream_close()
  68. {
  69. $this
  70. ->given(
  71. $wrapper = new SUT(),
  72. $this->openFile($wrapper)
  73. )
  74. ->when($result = $wrapper->stream_close())
  75. ->then
  76. ->variable($result)
  77. ->isNull()
  78. ->variable($wrapper->getStream())
  79. ->isNull()
  80. ->variable($wrapper->getStreamName())
  81. ->isNull();
  82. }
  83. public function case_stream_not_eof()
  84. {
  85. $this
  86. ->given(
  87. $wrapper = new SUT(),
  88. $this->openFile($wrapper, 'foo'),
  89. fseek($wrapper->getStream(), 0, SEEK_SET)
  90. )
  91. ->when($result = $wrapper->stream_eof())
  92. ->then
  93. ->boolean($result)
  94. ->isFalse();
  95. }
  96. public function case_stream_eof()
  97. {
  98. $this
  99. ->given(
  100. $this->function->feof = true,
  101. $wrapper = new SUT()
  102. )
  103. ->when($result = $wrapper->stream_eof())
  104. ->then
  105. ->boolean($result)
  106. ->isTrue();
  107. }
  108. public function case_stream_flush()
  109. {
  110. $this
  111. ->given(
  112. $wrapper = new SUT(),
  113. $this->openFile($wrapper)
  114. )
  115. ->when($result = $wrapper->stream_flush())
  116. ->then
  117. ->boolean($result)
  118. ->isTrue();
  119. }
  120. public function _case_stream_xxx_lock($operation)
  121. {
  122. $this
  123. ->given(
  124. $this->function->flock = function ($resource, $operation) use (&$_resource, &$_operation) {
  125. $_resource = $resource;
  126. $_operation = $operation;
  127. if ($operation === LOCK_NB) {
  128. return true;
  129. }
  130. return flock($resource, $operation);
  131. },
  132. $wrapper = new SUT(),
  133. $this->openFile($wrapper)
  134. )
  135. ->when($result = $wrapper->stream_lock($operation))
  136. ->then
  137. ->boolean($result)
  138. ->isTrue()
  139. ->resource($_resource)
  140. ->isStream()
  141. ->isIdenticalTo($wrapper->getStream())
  142. ->integer($_operation)
  143. ->isEqualTo($operation);
  144. }
  145. public function case_stream_shared_lock()
  146. {
  147. return $this->_case_stream_xxx_lock(LOCK_SH);
  148. }
  149. public function case_stream_exclusive_lock()
  150. {
  151. return $this->_case_stream_xxx_lock(LOCK_EX);
  152. }
  153. public function case_stream_release_lock()
  154. {
  155. return $this->_case_stream_xxx_lock(LOCK_UN);
  156. }
  157. public function case_stream_not_blocking_lock()
  158. {
  159. return $this->_case_stream_xxx_lock(LOCK_NB);
  160. }
  161. public function _case_metadata_touch_with_xxx_arguments($arguments, $path, $time, $atime)
  162. {
  163. $this
  164. ->given(
  165. $this->function->touch = function ($path, $time, $atime) use (&$_path, &$_time, &$_atime) {
  166. $_path = $path;
  167. $_time = $time;
  168. $_atime = $atime;
  169. return true;
  170. },
  171. $wrapper = new SUT()
  172. )
  173. ->when($result = $wrapper->stream_metadata($path, STREAM_META_TOUCH, $arguments))
  174. ->then
  175. ->boolean($result)
  176. ->isTrue()
  177. ->string($_path)
  178. ->isEqualTo($path)
  179. ->variable($_time)
  180. ->isEqualTo($time)
  181. ->variable($_atime)
  182. ->isEqualTo($atime);
  183. }
  184. public function case_metadata_touch_with_no_argument()
  185. {
  186. return $this->_case_metadata_touch_with_xxx_arguments([], 'foo', null, null);
  187. }
  188. public function case_metadata_touch_with_time()
  189. {
  190. return $this->_case_metadata_touch_with_xxx_arguments([42], 'foo', 42, null);
  191. }
  192. public function case_metadata_touch_with_time_and_atime()
  193. {
  194. return $this->_case_metadata_touch_with_xxx_arguments([42, 777], 'foo', 42, 777);
  195. }
  196. public function _case_metadata_owner_xxx($owner)
  197. {
  198. $this
  199. ->given(
  200. $this->function->chown = function ($path, $user) use (&$_path, &$_user) {
  201. $_path = $path;
  202. $_user = $user;
  203. return true;
  204. },
  205. $path = 'foo',
  206. $user = 'gordon',
  207. $wrapper = new SUT()
  208. )
  209. ->when($result = $wrapper->stream_metadata('foo', $owner, $user))
  210. ->then
  211. ->boolean($result)
  212. ->isTrue()
  213. ->string($path)
  214. ->isEqualTo($_path)
  215. ->string($user)
  216. ->isEqualTo($_user);
  217. }
  218. public function case_metadata_owner()
  219. {
  220. return $this->_case_metadata_owner_xxx(STREAM_META_OWNER);
  221. }
  222. public function case_metadata_owner_name()
  223. {
  224. return $this->_case_metadata_owner_xxx(STREAM_META_OWNER_NAME);
  225. }
  226. public function _case_metadata_group_xxx($grp)
  227. {
  228. $this
  229. ->given(
  230. $this->function->chgrp = function ($path, $group) use (&$_path, &$_group) {
  231. $_path = $path;
  232. $_group = $group;
  233. return true;
  234. },
  235. $path = 'foo',
  236. $group = 'root',
  237. $wrapper = new SUT()
  238. )
  239. ->when($result = $wrapper->stream_metadata('foo', $grp, $group))
  240. ->then
  241. ->boolean($result)
  242. ->isTrue()
  243. ->string($path)
  244. ->isEqualTo($_path)
  245. ->string($group)
  246. ->isEqualTo($_group);
  247. }
  248. public function case_metadata_group()
  249. {
  250. return $this->_case_metadata_group_xxx(STREAM_META_GROUP);
  251. }
  252. public function case_metadata_group_name()
  253. {
  254. return $this->_case_metadata_group_xxx(STREAM_META_GROUP_NAME);
  255. }
  256. public function case_metadata_access()
  257. {
  258. $this
  259. ->given(
  260. $this->function->chmod = function ($path, $mode) use (&$_path, &$_mode) {
  261. $_path = $path;
  262. $_mode = $mode;
  263. return true;
  264. },
  265. $path = 'foo',
  266. $mode = 0755,
  267. $wrapper = new SUT()
  268. )
  269. ->when($result = $wrapper->stream_metadata('foo', STREAM_META_ACCESS, $mode))
  270. ->then
  271. ->boolean($result)
  272. ->isTrue()
  273. ->string($path)
  274. ->isEqualTo($_path)
  275. ->integer($mode)
  276. ->isEqualTo($_mode);
  277. }
  278. public function case_metadata_default()
  279. {
  280. $this
  281. ->given(
  282. $option = 0,
  283. $mode = 0,
  284. $wrapper = new SUT()
  285. )
  286. ->when($result = $wrapper->stream_metadata('foo', $option, $mode))
  287. ->then
  288. ->boolean($result)
  289. ->isFalse();
  290. }
  291. public function case_stream_open()
  292. {
  293. $this
  294. ->given(
  295. $this->function->fopen = function ($path, $mode, $options) use (&$_path, &$_mode, &$_options, &$_openedPath) {
  296. $_path = $path;
  297. $_mode = $mode;
  298. $_options = $options;
  299. return fopen($path, $mode, $options);
  300. },
  301. $wrapper = new SUT(),
  302. $path = 'hoa://Test/Vfs/Foo?type=file',
  303. $mode = 'r',
  304. $options = STREAM_USE_PATH
  305. )
  306. ->when($result = $wrapper->stream_open($path, $mode, $options, $openedPath))
  307. ->then
  308. ->boolean($result)
  309. ->isTrue()
  310. ->string(SUT::realPath($path, true))
  311. ->isEqualTo($_path)
  312. ->string($mode)
  313. ->isEqualTo($_mode)
  314. ->integer($options)
  315. ->isEqualTo($_options & STREAM_USE_PATH)
  316. ->resource($openedPath)
  317. ->isStream()
  318. ->isIdenticalTo($wrapper->getStream())
  319. ->string($wrapper->getStreamName())
  320. ->isEqualTo('atoum://Foo');
  321. }
  322. public function case_stream_open_not_hoa_protocol()
  323. {
  324. $this
  325. ->given(
  326. $wrapper = new SUT(),
  327. $path = LUT::NO_RESOLUTION,
  328. $mode = 'r',
  329. $options = STREAM_USE_PATH
  330. )
  331. ->when($result = $wrapper->stream_open($path, $mode, $options, $openedPath))
  332. ->then
  333. ->boolean($result)
  334. ->isFalse();
  335. }
  336. public function case_stream_open_not_a_resource()
  337. {
  338. $this
  339. ->given(
  340. $this->function->fopen = function ($path, $mode, $options) use (&$_path, &$_mode, &$_options, &$_openedPath) {
  341. $_path = $path;
  342. $_mode = $mode;
  343. $_options = $options;
  344. return fopen($path, $mode, $options);
  345. },
  346. $this->function->is_resource = false,
  347. $wrapper = new SUT(),
  348. $path = 'hoa://Test/Vfs/Foo?type=file',
  349. $mode = 'r',
  350. $options = STREAM_USE_PATH
  351. )
  352. ->when($result = $wrapper->stream_open($path, $mode, $options, $openedPath))
  353. ->then
  354. ->boolean($result)
  355. ->isFalse()
  356. ->string(SUT::realPath($path, true))
  357. ->isEqualTo($_path)
  358. ->string($mode)
  359. ->isEqualTo($_mode)
  360. ->integer($options)
  361. ->isEqualTo($_options & STREAM_USE_PATH)
  362. ->resource($openedPath)
  363. ->isStream();
  364. }
  365. public function case_stream_read()
  366. {
  367. $this
  368. ->given(
  369. $this->function->fread = function ($resource, $count) use (&$_resource, &$_count) {
  370. $_resource = $resource;
  371. $_count = $count;
  372. return fread($resource, $count);
  373. },
  374. $wrapper = new SUT(),
  375. $count = 42,
  376. $this->openFile($wrapper, str_repeat('@', $count))
  377. )
  378. ->when($result = $wrapper->stream_read($count))
  379. ->then
  380. ->string($result)
  381. ->hasLength($count)
  382. ->resource($_resource)
  383. ->isStream()
  384. ->isIdenticalTo($wrapper->getStream())
  385. ->integer($_count)
  386. ->isEqualTo($count);
  387. }
  388. public function _case_stream_seek_xxx($offset, $whence)
  389. {
  390. return
  391. $this
  392. ->given(
  393. $this->function->fseek = function ($resource, $offset, $whence) use (&$_resource, &$_offset, &$_whence) {
  394. $_resource = $resource;
  395. $_offset = $offset;
  396. $_whence = $whence;
  397. return fseek($resource, $offset, $whence);
  398. },
  399. $wrapper = new SUT(),
  400. $this->openFile($wrapper, 'foobar')
  401. )
  402. ->when($result = $wrapper->stream_seek($offset, $whence))
  403. ->then
  404. ->boolean($result)
  405. ->isTrue()
  406. ->resource($_resource)
  407. ->isStream()
  408. ->isIdenticalTo($wrapper->getStream())
  409. ->integer($offset)
  410. ->isEqualTo($_offset)
  411. ->integer($whence)
  412. ->isEqualTo($_whence)
  413. ->integer(ftell($wrapper->getStream()));
  414. }
  415. public function case_stream_seek_set()
  416. {
  417. return
  418. $this
  419. ->_case_stream_seek_xxx(3, SEEK_SET)
  420. ->isEqualTo(3);
  421. }
  422. public function case_stream_seek_current()
  423. {
  424. return
  425. $this
  426. ->_case_stream_seek_xxx(4, SEEK_CUR)
  427. ->isEqualTo(4);
  428. }
  429. public function case_stream_seek_end()
  430. {
  431. return
  432. $this
  433. ->_case_stream_seek_xxx(-4, SEEK_END)
  434. ->isEqualTo(2);
  435. }
  436. public function case_stream_stat()
  437. {
  438. $this
  439. ->given(
  440. $this->function->fstat = function ($resource) use (&$_resource) {
  441. $_resource = $resource;
  442. return fstat($resource);
  443. },
  444. $wrapper = new SUT(),
  445. $this->openFile($wrapper)
  446. )
  447. ->when($result = $wrapper->stream_stat())
  448. ->then
  449. ->array($result)
  450. ->resource($_resource)
  451. ->isStream()
  452. ->isIdenticalTo($wrapper->getStream());
  453. }
  454. public function case_stream_tell()
  455. {
  456. $this
  457. ->given(
  458. $this->function->ftell = function ($resource) use (&$_resource) {
  459. $_resource = $resource;
  460. return ftell($resource);
  461. },
  462. $wrapper = new SUT(),
  463. $this->openFile($wrapper, 'foo'),
  464. $wrapper->stream_seek(2)
  465. )
  466. ->when($result = $wrapper->stream_tell())
  467. ->then
  468. ->integer($result)
  469. ->isEqualTo(2)
  470. ->resource($_resource)
  471. ->isStream()
  472. ->isIdenticalTo($wrapper->getStream());
  473. }
  474. public function case_stream_truncate()
  475. {
  476. $this
  477. ->given(
  478. $this->function->ftruncate = function ($resource, $size) use (&$_resource, &$_size) {
  479. $_resource = $resource;
  480. $_size = $size;
  481. return ftruncate($resource, $size);
  482. },
  483. $wrapper = new SUT(),
  484. $this->openFile($wrapper, 'foobar'),
  485. $size = 3
  486. )
  487. ->when($result = $wrapper->stream_truncate($size))
  488. ->then
  489. ->boolean($result)
  490. ->isTrue()
  491. ->resource($_resource)
  492. ->isStream()
  493. ->isIdenticalTo($wrapper->getStream())
  494. ->integer($size)
  495. ->isEqualTo($_size)
  496. ->integer($wrapper->stream_tell())
  497. ->isEqualTo(0)
  498. ->let($wrapper->stream_seek(0, SEEK_END))
  499. ->integer($wrapper->stream_tell())
  500. ->isEqualTo(3);
  501. }
  502. public function case_stream_write()
  503. {
  504. $this
  505. ->given(
  506. $this->function->fwrite = function ($resource, $data) use (&$_resource, &$_data) {
  507. $_resource = $resource;
  508. $_data = $data;
  509. return fwrite($resource, $data);
  510. },
  511. $wrapper = new SUT(),
  512. $wrapper->stream_open('hoa://Test/Vfs/Foo?type=file', 'wb+', STREAM_USE_PATH, $openedPath),
  513. $data = 'foo'
  514. )
  515. ->when($result = $wrapper->stream_write($data))
  516. ->then
  517. ->integer($result)
  518. ->isEqualTo(strlen($data))
  519. ->resource($_resource)
  520. ->isStream()
  521. ->isIdenticalTo($wrapper->getStream())
  522. ->string($_data)
  523. ->isEqualTo($data)
  524. ->let($wrapper->stream_seek(0))
  525. ->string($wrapper->stream_read(3))
  526. ->isEqualTo($data);
  527. }
  528. public function case_dir_closedir()
  529. {
  530. $this
  531. ->given(
  532. $wrapper = new SUT(),
  533. $this->openDirectory($wrapper)
  534. )
  535. ->when($result = $wrapper->dir_closedir())
  536. ->then
  537. ->variable($result)
  538. ->isNull()
  539. ->variable($wrapper->getStream())
  540. ->isNull()
  541. ->variable($wrapper->getStreamName())
  542. ->isNull();
  543. }
  544. public function case_dir_opendir()
  545. {
  546. $this
  547. ->given(
  548. $this->function->opendir = function ($path) use (&$_path) {
  549. $_path = $path;
  550. return opendir($path);
  551. },
  552. $wrapper = new SUT(),
  553. $path = 'hoa://Test/Vfs/Bar?type=directory',
  554. $options = 0
  555. )
  556. ->when($result = $wrapper->dir_opendir($path, $options))
  557. ->then
  558. ->boolean($result)
  559. ->isTrue()
  560. ->string(SUT::realPath($path, true))
  561. ->isEqualTo($_path)
  562. ->resource($wrapper->getStream())
  563. ->isStream()
  564. ->string($wrapper->getStreamName())
  565. ->isEqualTo('atoum://Bar');
  566. }
  567. public function case_dir_opendir_not_a_resource()
  568. {
  569. $this
  570. ->given(
  571. $this->function->opendir = function ($path) use (&$_path) {
  572. $_path = $path;
  573. return false;
  574. },
  575. $wrapper = new SUT(),
  576. $path = 'hoa://Test/Vfs/Bar?type=directory',
  577. $options = 0
  578. )
  579. ->when($result = $wrapper->dir_opendir($path, $options))
  580. ->then
  581. ->boolean($result)
  582. ->isFalse()
  583. ->string(SUT::realPath($path, true))
  584. ->isEqualTo($_path)
  585. ->variable($wrapper->getStream())
  586. ->isNull()
  587. ->variable($wrapper->getStreamName())
  588. ->isNull();
  589. }
  590. public function case_dir_readdir()
  591. {
  592. $this
  593. ->given(
  594. $this->function->readdir = function ($resource) use (&$_resource) {
  595. $_resource = $resource;
  596. return readdir($resource);
  597. },
  598. $wrapper = new SUT(),
  599. $this->openDirectory($wrapper, ['Baz', 'Qux'])
  600. )
  601. ->when($result = $wrapper->dir_readdir())
  602. ->then
  603. ->string($result)
  604. ->isEqualTo('Baz')
  605. ->resource($_resource)
  606. ->isIdenticalTo($wrapper->getStream());
  607. }
  608. public function case_dir_readdir_until_eod()
  609. {
  610. $this
  611. ->given(
  612. $this->function->readdir = function ($resource) use (&$_resource) {
  613. $_resource = $resource;
  614. return readdir($resource);
  615. },
  616. $wrapper = new SUT(),
  617. $this->openDirectory($wrapper, ['Baz', 'Qux'])
  618. )
  619. ->when($result = $wrapper->dir_readdir())
  620. ->then
  621. ->string($result)
  622. ->isEqualTo('Baz')
  623. ->resource($_resource)
  624. ->isIdenticalTo($wrapper->getStream())
  625. ->when($result = $wrapper->dir_readdir())
  626. ->then
  627. ->string($result)
  628. ->isEqualTo('Qux')
  629. ->when($result = $wrapper->dir_readdir())
  630. ->then
  631. ->boolean($result)
  632. ->isFalse();
  633. }
  634. public function case_dir_rewinddir()
  635. {
  636. $this
  637. ->given(
  638. $this->function->rewinddir = function ($resource) use (&$_resource) {
  639. $_resource = $resource;
  640. return rewinddir($resource);
  641. },
  642. $wrapper = new SUT(),
  643. $this->openDirectory($wrapper, ['Baz']),
  644. $wrapper->dir_readdir()
  645. )
  646. ->when($result = $wrapper->dir_rewinddir())
  647. ->then
  648. ->variable($result)
  649. ->isNull()
  650. ->when($result = $wrapper->dir_readdir())
  651. ->then
  652. ->string($result)
  653. ->isEqualTo('Baz')
  654. ->resource($_resource)
  655. ->isIdenticalTo($wrapper->getStream());
  656. }
  657. public function case_dir_mkdir()
  658. {
  659. $this
  660. ->given(
  661. $this->function->mkdir = function ($path, $mode, $options) use (&$_path, &$_mode, &$_options) {
  662. $_path = $path;
  663. $_mode = $mode;
  664. $_options = $options;
  665. return true;
  666. },
  667. $wrapper = new SUT(),
  668. $this->openDirectory($wrapper),
  669. $path = 'Baz',
  670. $mode = 0755,
  671. $options = STREAM_MKDIR_RECURSIVE
  672. )
  673. ->when($result = $wrapper->mkdir($path, $mode, $options))
  674. ->then
  675. ->boolean($result)
  676. ->isTrue()
  677. ->string($_path)
  678. ->isEqualTo($path)
  679. ->integer($_mode)
  680. ->isEqualTo($_mode)
  681. ->integer($_options)
  682. ->isEqualTo($options | STREAM_MKDIR_RECURSIVE);
  683. }
  684. public function case_rename()
  685. {
  686. $this
  687. ->given(
  688. $this->function->rename = function ($from, $to) use (&$_from, &$_to) {
  689. $_to = $to;
  690. $_from = $from;
  691. return rename($from, $to);
  692. },
  693. $wrapper = new SUT(),
  694. $this->openFile($wrapper),
  695. $from = 'hoa://Test/Vfs/Foo?type=file',
  696. $to = 'hoa://Test/Vfs/Oof?type=file'
  697. )
  698. ->when($result = $wrapper->rename($from, $to))
  699. ->then
  700. ->boolean($result)
  701. ->isTrue()
  702. ->string($_from)
  703. ->isEqualTo(SUT::realPath($from))
  704. ->string($_to)
  705. ->isEqualTo(SUT::realPath($_to, false));
  706. }
  707. public function case_rmdir()
  708. {
  709. $this
  710. ->given(
  711. $this->function->rmdir = function ($path) use (&$_path) {
  712. $_path = $path;
  713. return rmdir($path);
  714. },
  715. $wrapper = new SUT(),
  716. $this->openDirectory($wrapper)
  717. )
  718. ->when($result = $wrapper->rmdir('hoa://Test/Vfs/Bar?type=directory', 0))
  719. ->then
  720. ->boolean($result)
  721. ->isTrue();
  722. }
  723. public function case_rmdir_a_file()
  724. {
  725. $this
  726. ->given(
  727. $wrapper = new SUT(),
  728. $this->openFile($wrapper)
  729. )
  730. ->when($result = $wrapper->rmdir('hoa://Test/Vfs/Foo?type=file', 0))
  731. ->then
  732. ->boolean($result)
  733. ->isFalse();
  734. }
  735. public function case_unlink()
  736. {
  737. $this
  738. ->given(
  739. $wrapper = new SUT(),
  740. $this->openFile($wrapper)
  741. )
  742. ->when($result = $wrapper->unlink('hoa://Test/Vfs/Foo?type=file'))
  743. ->then
  744. ->boolean($result)
  745. ->isTrue();
  746. }
  747. public function case_rmdir_a_directory()
  748. {
  749. $this
  750. ->given(
  751. $wrapper = new SUT(),
  752. $this->openDirectory($wrapper)
  753. )
  754. ->when($result = $wrapper->unlink('hoa://Test/Vfs/Bar?type=directory'))
  755. ->then
  756. ->boolean($result)
  757. ->isFalse();
  758. }
  759. public function case_url_stat()
  760. {
  761. $this
  762. ->given(
  763. $this->function->stat = function ($path) use (&$_path) {
  764. $_path = $path;
  765. return stat($path);
  766. },
  767. $wrapper = new SUT(),
  768. $this->openFile($wrapper),
  769. $path = 'hoa://Test/Vfs/Foo?type=file'
  770. )
  771. ->when($result = $wrapper->url_stat($path, 0))
  772. ->then
  773. ->let(
  774. $keys = [
  775. 'dev',
  776. 'ino',
  777. 'mode',
  778. 'nlink',
  779. 'uid',
  780. 'gid',
  781. 'rdev',
  782. 'size',
  783. 'atime',
  784. 'mtime',
  785. 'ctime',
  786. 'blksize',
  787. 'blocks'
  788. ]
  789. )
  790. ->array($result)
  791. ->hasSize(26)
  792. ->hasKeys($keys)
  793. ->hasKeys(array_keys($keys))
  794. ->string($_path)
  795. ->isEqualTo(SUT::realPath($path));
  796. }
  797. public function case_url_stat_not_hoa_protocol()
  798. {
  799. $this
  800. ->given(
  801. $wrapper = new SUT(),
  802. $path = LUT::NO_RESOLUTION
  803. )
  804. ->when(function () use ($wrapper, $path) {
  805. $wrapper->url_stat($path, 0);
  806. })
  807. ->then
  808. ->error()
  809. ->exists();
  810. }
  811. protected function openFile(SUT $wrapper, $content = '')
  812. {
  813. $wrapper->stream_open('hoa://Test/Vfs/Foo?type=file', 'wb+', STREAM_USE_PATH, $openedPath);
  814. fwrite($openedPath, $content, strlen($content));
  815. fseek($openedPath, 0, SEEK_SET);
  816. return $wrapper;
  817. }
  818. protected function openDirectory(SUT $wrapper, array $children = [])
  819. {
  820. $wrapper->dir_opendir('hoa://Test/Vfs/Bar?type=directory', 0);
  821. foreach ($children as $child) {
  822. resolve('hoa://Test/Vfs/Bar/' . $child . '?type=file');
  823. }
  824. return $wrapper;
  825. }
  826. }