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