Stream.php 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795
  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\Stream\Test\Unit;
  36. use Hoa\Event;
  37. use Hoa\Stream as LUT;
  38. use Hoa\Test;
  39. /**
  40. * Class \Hoa\Stream\Test\Unit\Stream.
  41. *
  42. * Test suite of the stream class.
  43. *
  44. * @copyright Copyright © 2007-2017 Hoa community
  45. * @license New BSD License
  46. */
  47. class Stream extends Test\Unit\Suite
  48. {
  49. public function case_interfaces()
  50. {
  51. $this
  52. ->when($result = new SUT(__FILE__))
  53. ->then
  54. ->object($result)
  55. ->isInstanceOf(LUT\IStream\Stream::class)
  56. ->isInstanceOf(Event\Listenable::class);
  57. }
  58. public function case_constants()
  59. {
  60. $this
  61. ->integer(SUT::NAME)
  62. ->isEqualTo(0)
  63. ->integer(SUT::HANDLER)
  64. ->isEqualTo(1)
  65. ->integer(SUT::RESOURCE)
  66. ->isEqualTo(2)
  67. ->integer(SUT::CONTEXT)
  68. ->isEqualTo(3);
  69. }
  70. public function case_construct()
  71. {
  72. $this
  73. ->given($name = __FILE__)
  74. ->when($result = new SUT($name))
  75. ->then
  76. ->string($result->getStreamName())
  77. ->isEqualTo($name)
  78. ->boolean($this->invoke($result)->hasBeenDeferred())
  79. ->isFalse()
  80. ->let($listener = $this->invoke($result)->getListener())
  81. ->object($listener)
  82. ->isInstanceOf(Event\Listener::class)
  83. ->boolean($listener->listenerExists('authrequire'))
  84. ->isTrue()
  85. ->boolean($listener->listenerExists('authresult'))
  86. ->isTrue()
  87. ->boolean($listener->listenerExists('complete'))
  88. ->isTrue()
  89. ->boolean($listener->listenerExists('connect'))
  90. ->isTrue()
  91. ->boolean($listener->listenerExists('failure'))
  92. ->isTrue()
  93. ->boolean($listener->listenerExists('mimetype'))
  94. ->isTrue()
  95. ->boolean($listener->listenerExists('progress'))
  96. ->isTrue()
  97. ->boolean($listener->listenerExists('redirect'))
  98. ->isTrue()
  99. ->boolean($listener->listenerExists('resolve'))
  100. ->isTrue()
  101. ->boolean($listener->listenerExists('size'))
  102. ->isTrue()
  103. ->boolean(Event::eventExists('hoa://Event/Stream/' . $name))
  104. ->isTrue()
  105. ->boolean(Event::eventExists('hoa://Event/Stream/' . $name . ':close-before'))
  106. ->isTrue();
  107. }
  108. public function case_construct_with_a_context()
  109. {
  110. $this
  111. ->given(
  112. $name = __FILE__,
  113. $contextName = 'foo',
  114. LUT\Context::getInstance($contextName)
  115. )
  116. ->when($result = new SUT($name, $contextName))
  117. ->then
  118. ->string($result->getStreamName())
  119. ->isEqualTo($name)
  120. ->boolean($this->invoke($result)->hasBeenDeferred())
  121. ->isFalse()
  122. ->object($this->invoke($result)->getListener())
  123. ->isInstanceOf(Event\Listener::class);
  124. }
  125. public function case_construct_with_deferred_opening()
  126. {
  127. $this
  128. ->given($name = __FILE__)
  129. ->when($result = new SUT($name, null, true))
  130. ->then
  131. ->boolean($this->invoke($result)->hasBeenDeferred())
  132. ->isTrue()
  133. ->boolean($result->isOpened())
  134. ->isFalse()
  135. ->variable($result->getStreamName())
  136. ->isNull();
  137. }
  138. public function case_open()
  139. {
  140. $this
  141. ->given(
  142. $name = __FILE__,
  143. $stream = new SUT($name, null, true)
  144. )
  145. ->when($result = $stream->open())
  146. ->then
  147. ->object($result)
  148. ->isIdenticalTo($stream)
  149. ->boolean($this->invoke($result)->hasBeenDeferred())
  150. ->isTrue()
  151. ->boolean($result->isOpened())
  152. ->isTrue()
  153. ->string($result->getStreamName())
  154. ->isEqualTo($name)
  155. ->integer($result->getStreamBufferSize())
  156. ->isEqualTo(SUT::DEFAULT_BUFFER_SIZE);
  157. }
  158. public function case_close()
  159. {
  160. $this
  161. ->given(
  162. $name = __FILE__,
  163. $stream = new SUT($name),
  164. $resource = $stream->getStream(),
  165. $context = $stream->getStreamContext()
  166. )
  167. ->when($result = $stream->close())
  168. ->then
  169. ->variable($result)
  170. ->isNull()
  171. ->boolean($stream->isOpened())
  172. ->isFalse()
  173. ->variable(SUT::getStreamHandler($stream))
  174. ->isNull()
  175. ->variable($stream->getStreamName())
  176. ->isEqualTo($name)
  177. ->variable($stream->getStream())
  178. ->isEqualTo($resource)
  179. ->variable($stream->getStreamContext())
  180. ->isEqualTo($context)
  181. ->boolean(Event::eventExists('hoa://Event/Stream/' . $name))
  182. ->isFalse()
  183. ->boolean(Event::eventExists('hoa://Event/Stream/' . $name . ':close-before'))
  184. ->isFalse();
  185. }
  186. public function case_close_more_than_once()
  187. {
  188. $this
  189. ->given(
  190. $name = __FILE__,
  191. $stream = new SUT($name),
  192. $close1 = $stream->close()
  193. )
  194. ->when($result = $stream->close())
  195. ->then
  196. ->variable($result)
  197. ->isIdenticalTo($close1);
  198. }
  199. public function case_open_close_open()
  200. {
  201. $this
  202. ->given(
  203. $name = __FILE__,
  204. $stream = new SUT($name, null, true),
  205. $stream->open(),
  206. $resource = $stream->getStream(),
  207. $context = $stream->getStreamContext(),
  208. $handler = SUT::getStreamHandler($stream),
  209. $this->function->stream_set_write_buffer = 0,
  210. $stream->setStreamBuffer(42),
  211. $stream->close()
  212. )
  213. ->when($result = $stream->open())
  214. ->then
  215. ->string($result->getStreamName())
  216. ->isEqualTo($name)
  217. ->resource($result->getStream())
  218. ->isNotEqualTo($resource)
  219. ->object($handler)
  220. ->isIdenticalTo($result)
  221. ->object($this->invoke($stream)->getListener())
  222. ->isInstanceOf(Event\Listener::class)
  223. ->boolean(Event::eventExists('hoa://Event/Stream/' . $name))
  224. ->isTrue()
  225. ->boolean(Event::eventExists('hoa://Event/Stream/' . $name . ':close-before'))
  226. ->isTrue()
  227. ->integer($stream->getStreamBufferSize())
  228. ->isEqualTo(SUT::DEFAULT_BUFFER_SIZE);
  229. }
  230. public function case_close_event_close_before()
  231. {
  232. $self = $this;
  233. $this
  234. ->given(
  235. $name = 'hoa://Test/Vfs/Foo?type=file',
  236. $stream = new SUT($name),
  237. Event::getEvent('hoa://Event/Stream/' . $name . ':close-before')->attach(
  238. function (Event\Bucket $bucket) use ($self, &$called) {
  239. $called = true;
  240. $self
  241. ->variable($bucket->getData())
  242. ->isNull()
  243. ->boolean($bucket->getSource()->isOpened())
  244. ->isTrue();
  245. }
  246. )
  247. )
  248. ->when($result = $stream->close())
  249. ->then
  250. ->boolean($called)
  251. ->isTrue();
  252. }
  253. public function case_get_stream_name()
  254. {
  255. $this
  256. ->given(
  257. $name = __FILE__,
  258. $stream = new SUT($name)
  259. )
  260. ->when($result = $stream->getStreamName())
  261. ->then
  262. ->string($result)
  263. ->isEqualTo($name);
  264. }
  265. public function case_get_stream()
  266. {
  267. $this
  268. ->given(
  269. $name = __FILE__,
  270. $stream = new SUT($name)
  271. )
  272. ->when($result = $stream->getStream())
  273. ->then
  274. ->resource($result)
  275. ->isStream($name);
  276. }
  277. public function case_get_stream_context()
  278. {
  279. $this
  280. ->given(
  281. $name = __FILE__,
  282. $contextName = 'foo',
  283. $context = LUT\Context::getInstance($contextName),
  284. $stream = new SUT($name, $contextName)
  285. )
  286. ->when($result = $stream->getStreamContext())
  287. ->then
  288. ->object($result)
  289. ->isIdenticalTo($context);
  290. }
  291. public function case_get_stream_context_with_no_context_given()
  292. {
  293. $this
  294. ->given(
  295. $name = __FILE__,
  296. $stream = new SUT($name)
  297. )
  298. ->when($result = $stream->getStreamContext())
  299. ->then
  300. ->variable($result)
  301. ->isNull();
  302. }
  303. public function case_get_stream_handler()
  304. {
  305. $this
  306. ->given(
  307. $name = __FILE__,
  308. $stream = new SUT($name)
  309. )
  310. ->when($result = SUT::getStreamHandler($name))
  311. ->then
  312. ->object($result)
  313. ->isIdenticalTo($result);
  314. }
  315. public function case_get_stream_handler_of_unknown_stream()
  316. {
  317. $this
  318. ->when($result = SUT::getStreamHandler('foo'))
  319. ->then
  320. ->variable($result)
  321. ->isNull();
  322. }
  323. public function case__set_stream()
  324. {
  325. $this
  326. ->given(
  327. $stream = new SUT(__FILE__),
  328. $oldStream = $stream->getStream(),
  329. $newStream = fopen('php://memory', 'rb')
  330. )
  331. ->when($result = $stream->_setStream($newStream))
  332. ->then
  333. ->resource($result)
  334. ->isIdenticalTo($oldStream)
  335. ->isStream()
  336. ->resource($stream->getStream())
  337. ->isStream()
  338. ->isIdenticalTo($newStream);
  339. }
  340. public function case__set_stream_invalid_resource()
  341. {
  342. $this
  343. ->given($stream = new SUT(__FILE__))
  344. ->exception(function () use ($stream) {
  345. $stream->_setStream(true);
  346. })
  347. ->isInstanceOf(LUT\Exception::class);
  348. }
  349. public function case__set_stream_unknown_resource()
  350. {
  351. $this
  352. ->given(
  353. $stream = new SUT(__FILE__),
  354. $oldStream = $stream->getStream(),
  355. $newStream = fopen('php://memory', 'rb'),
  356. $this->function->is_resource = false,
  357. $this->function->gettype = 'resource',
  358. $this->function->get_resource_type = 'Unknown'
  359. )
  360. ->when($result = $stream->_setStream($newStream))
  361. ->then
  362. ->resource($result)
  363. ->isIdenticalTo($oldStream)
  364. ->isStream()
  365. ->resource($stream->getStream())
  366. ->isStream()
  367. ->isIdenticalTo($newStream);
  368. }
  369. public function case_is_opened()
  370. {
  371. $this
  372. ->given($stream = new SUT(__FILE__))
  373. ->when($result = $stream->isOpened())
  374. ->then
  375. ->boolean($result)
  376. ->isTrue();
  377. }
  378. public function case_is_not_opened()
  379. {
  380. $this
  381. ->given($stream = new SUT(__FILE__, null, true))
  382. ->when($result = $stream->isOpened())
  383. ->then
  384. ->boolean($result)
  385. ->isFalse()
  386. ->when(
  387. $stream->open(),
  388. $result = $stream->isOpened()
  389. )
  390. ->then
  391. ->boolean($result)
  392. ->isTrue();
  393. }
  394. public function case_set_stream_timeout()
  395. {
  396. $self = $this;
  397. $this
  398. ->given(
  399. $stream = new SUT(__FILE__),
  400. $this->function->stream_set_timeout = function ($_stream, $_seconds, $_microseconds) use ($self, $stream, &$called) {
  401. $called = true;
  402. $self
  403. ->resource($_stream)
  404. ->isIdenticalTo($stream->getStream())
  405. ->integer($_seconds)
  406. ->isEqualTo(7)
  407. ->integer($_microseconds)
  408. ->isEqualTo(42);
  409. return true;
  410. }
  411. )
  412. ->when($result = $stream->setStreamTimeout(7, 42))
  413. ->then
  414. ->boolean($result)
  415. ->isTrue()
  416. ->boolean($called)
  417. ->isTrue();
  418. }
  419. public function case_has_been_deferred()
  420. {
  421. $this
  422. ->given($stream = new SUT(__FILE__, null, true))
  423. ->when($result = $this->invoke($stream)->hasBeenDeferred())
  424. ->then
  425. ->boolean($result)
  426. ->isTrue();
  427. }
  428. public function case_has_not_been_deferred()
  429. {
  430. $this
  431. ->given($stream = new SUT(__FILE__))
  432. ->when($result = $this->invoke($stream)->hasBeenDeferred())
  433. ->then
  434. ->boolean($result)
  435. ->isFalse();
  436. }
  437. public function case_has_timed_out()
  438. {
  439. $this
  440. ->given(
  441. $stream = new SUT(__FILE__),
  442. $this->function->stream_get_meta_data = [
  443. 'timed_out' => true
  444. ]
  445. )
  446. ->when($result = $stream->hasTimedOut())
  447. ->then
  448. ->boolean($result)
  449. ->isTrue();
  450. }
  451. public function case_has_not_timed_out()
  452. {
  453. $this
  454. ->given(
  455. $stream = new SUT(__FILE__),
  456. $this->function->stream_get_meta_data = [
  457. 'timed_out' => false
  458. ]
  459. )
  460. ->when($result = $stream->hasTimedOut())
  461. ->then
  462. ->boolean($result)
  463. ->isFalse();
  464. }
  465. public function case_set_stream_blocking()
  466. {
  467. $self = $this;
  468. $this
  469. ->given(
  470. $stream = new SUT(__FILE__),
  471. $this->function->stream_set_blocking = function ($_stream, $_mode) use ($self, $stream, &$called) {
  472. $called = true;
  473. $self
  474. ->resource($_stream)
  475. ->isIdenticalTo($stream->getStream())
  476. ->integer($_mode)
  477. ->isEqualTo(1);
  478. return true;
  479. }
  480. )
  481. ->when($result = $stream->setStreamBlocking(true))
  482. ->then
  483. ->boolean($result)
  484. ->isTrue()
  485. ->boolean($called)
  486. ->isTrue();
  487. }
  488. public function case_get_default_stream_buffer_size()
  489. {
  490. $self = $this;
  491. $this
  492. ->given($stream = new SUT(__FILE__))
  493. ->when($result = $stream->getStreamBufferSize())
  494. ->then
  495. ->integer($result)
  496. ->isEqualTo(8192);
  497. }
  498. public function case_set_stream_buffer()
  499. {
  500. $self = $this;
  501. $this
  502. ->given(
  503. $stream = new SUT(__FILE__),
  504. $this->function->stream_set_write_buffer = function ($_stream, $_buffer) use ($self, $stream, &$called) {
  505. $called = true;
  506. $self
  507. ->resource($_stream)
  508. ->isIdenticalTo($stream->getStream())
  509. ->integer($_buffer)
  510. ->isEqualTo(42);
  511. return 0;
  512. }
  513. )
  514. ->when($result = $stream->setStreamBuffer(42))
  515. ->then
  516. ->boolean($result)
  517. ->isTrue()
  518. ->boolean($called)
  519. ->isTrue()
  520. ->integer($stream->getStreamBufferSize())
  521. ->isEqualTo(42);
  522. }
  523. public function case_set_stream_buffer_fail()
  524. {
  525. $self = $this;
  526. $this
  527. ->given(
  528. $stream = new SUT(__FILE__),
  529. $oldStreamBufferSize = $stream->getStreamBufferSize(),
  530. $this->function->stream_set_write_buffer = function ($_stream, $_buffer) use ($self, $stream, &$called) {
  531. $called = true;
  532. $self
  533. ->resource($_stream)
  534. ->isIdenticalTo($stream->getStream())
  535. ->integer($_buffer)
  536. ->isEqualTo(42);
  537. return 1;
  538. }
  539. )
  540. ->when($result = $stream->setStreamBuffer(42))
  541. ->then
  542. ->boolean($result)
  543. ->isFalse()
  544. ->boolean($called)
  545. ->isTrue()
  546. ->integer($stream->getStreamBufferSize())
  547. ->isEqualTo($oldStreamBufferSize);
  548. }
  549. public function case_disable_stream_buffer()
  550. {
  551. $self = $this;
  552. $this
  553. ->given(
  554. $stream = new SUT(__FILE__),
  555. $this->function->stream_set_write_buffer = function ($_stream, $_buffer) use ($self, $stream, &$called) {
  556. $called = true;
  557. $self
  558. ->resource($_stream)
  559. ->isIdenticalTo($stream->getStream())
  560. ->integer($_buffer)
  561. ->isEqualTo(0);
  562. return 0;
  563. }
  564. )
  565. ->when($result = $stream->disableStreamBuffer())
  566. ->then
  567. ->boolean($result)
  568. ->isTrue()
  569. ->boolean($called)
  570. ->isTrue()
  571. ->integer($stream->getStreamBufferSize())
  572. ->isEqualTo(0);
  573. }
  574. public function case_get_stream_wrapper_name_with_no_wrapper()
  575. {
  576. $this
  577. ->given($stream = new SUT(__FILE__))
  578. ->when($result = $stream->getStreamWrapperName())
  579. ->then
  580. ->string($result)
  581. ->isEqualTo('file');
  582. }
  583. public function case_get_stream_wrapper_name()
  584. {
  585. $this
  586. ->given($stream = new SUT('hoa://Test/Vfs/Foo?type=file'))
  587. ->when($result = $stream->getStreamWrapperName())
  588. ->then
  589. ->string($result)
  590. ->isEqualTo('hoa');
  591. }
  592. public function case_get_stream_meta_data()
  593. {
  594. $this
  595. ->given($stream = new SUT(__FILE__))
  596. ->when($result = $stream->getStreamMetaData())
  597. ->then
  598. ->array($result)
  599. ->isEqualTo([
  600. 'timed_out' => false,
  601. 'blocked' => true,
  602. 'eof' => false,
  603. 'wrapper_type' => 'plainfile',
  604. 'stream_type' => 'STDIO',
  605. 'mode' => 'rb',
  606. 'unread_bytes' => 0,
  607. 'seekable' => true,
  608. 'uri' => __FILE__
  609. ]);
  610. }
  611. public function case_is_borrowing()
  612. {
  613. $this
  614. ->given(
  615. $streamA1 = new SUT(__FILE__),
  616. $streamA2 = new SUT(__FILE__)
  617. )
  618. ->when($result = $streamA2->isBorrowing())
  619. ->then
  620. ->boolean($result)
  621. ->isTrue()
  622. ->boolean($streamA1->isBorrowing())
  623. ->isFalse();
  624. }
  625. public function case_is_not_borrowing()
  626. {
  627. $this
  628. ->given($stream = new SUT(__FILE__))
  629. ->when($result = $stream->isBorrowing())
  630. ->then
  631. ->boolean($result)
  632. ->isFalse();
  633. }
  634. public function case_shutdown_destructor()
  635. {
  636. $this
  637. ->given(
  638. $stream = new \Mock\Hoa\Stream\Test\Unit\SUTWithPublicClose(__FILE__),
  639. $this->calling($stream)->_close = function () use (&$called) {
  640. $called = true;
  641. }
  642. )
  643. ->when($result = SUT::_Hoa_Stream())
  644. ->then
  645. ->boolean($called)
  646. ->isTrue();
  647. }
  648. public function case_destruct_an_opened_stream()
  649. {
  650. $this
  651. ->given(
  652. $stream = new \Mock\Hoa\Stream\Test\Unit\SUTWithPublicClose(__FILE__),
  653. $this->calling($stream)->_close = function () use (&$called) {
  654. $called = true;
  655. }
  656. )
  657. ->when($result = $stream->__destruct())
  658. ->then
  659. ->boolean($called)
  660. ->isTrue();
  661. }
  662. public function case_destruct_a_deferred_stream()
  663. {
  664. $this
  665. ->given(
  666. $stream = new \Mock\Hoa\Stream\Test\Unit\SUTWithPublicClose(__FILE__, null, true),
  667. $this->calling($stream)->_close = function () use (&$called) {
  668. $called = true;
  669. }
  670. )
  671. ->when($result = $stream->__destruct())
  672. ->then
  673. ->variable($called)
  674. ->isNull();
  675. }
  676. public function case_protocol_reach_id()
  677. {
  678. $this
  679. ->given(
  680. $name = 'hoa://Test/Vfs/Foo?type=file',
  681. $stream = new SUT($name)
  682. )
  683. ->when($result = resolve('hoa://Library/Stream#' . $name))
  684. ->then
  685. ->object($result)
  686. ->isIdenticalTo($stream);
  687. }
  688. public function case_protocol_reach_unknown_id()
  689. {
  690. $this
  691. ->given($name = 'hoa://Test/Vfs/Foo?type=file')
  692. ->when($result = resolve('hoa://Library/Stream#' . $name))
  693. ->then
  694. ->variable($result)
  695. ->isNull();
  696. }
  697. }
  698. class SUT extends LUT\Stream
  699. {
  700. protected function &_open($streamName, LUT\Context $context = null)
  701. {
  702. if (null === $context) {
  703. $out = fopen($streamName, 'rb');
  704. } else {
  705. $out = fopen($streamName, 'rb', false, $context->getContext());
  706. }
  707. return $out;
  708. }
  709. protected function _close()
  710. {
  711. return fclose($this->getStream());
  712. }
  713. }
  714. class SUTWithPublicClose extends SUT
  715. {
  716. public function _close()
  717. {
  718. return parent::_close();
  719. }
  720. }