1<?php
2namespace GuzzleHttp\Tests\Stream;
3
4use BadMethodCallException;
5use GuzzleHttp\Stream\Stream;
6use GuzzleHttp\Stream\FnStream;
7use PHPUnit\Framework\TestCase;
8
9/**
10 * @covers GuzzleHttp\Stream\FnStream
11 */
12class FnStreamTest extends TestCase
13{
14    public function testThrowsWhenNotImplemented()
15    {
16        $this->expectException(BadMethodCallException::class);
17        $this->expectExceptionMessage('seek() is not implemented in the FnStream');
18        (new FnStream([]))->seek(1);
19    }
20
21    public function testProxiesToFunction()
22    {
23        $s = new FnStream([
24            'read' => function ($len) {
25                $this->assertEquals(3, $len);
26                return 'foo';
27            },
28        ]);
29
30        $this->assertEquals('foo', $s->read(3));
31    }
32
33    public function testCanCloseOnDestruct()
34    {
35        $called = false;
36        $s = new FnStream([
37            'close' => function () use (&$called) {
38                $called = true;
39            },
40        ]);
41        unset($s);
42        $this->assertTrue($called);
43    }
44
45    /**
46     * @doesNotPerformAssertions
47     */
48    public function testDoesNotRequireClose()
49    {
50        $s = new FnStream([]);
51        unset($s);
52    }
53
54    public function testDecoratesStream()
55    {
56        $a = Stream::factory('foo');
57        $b = FnStream::decorate($a, []);
58        $this->assertEquals(3, $b->getSize());
59        $this->assertEquals($b->isWritable(), true);
60        $this->assertEquals($b->isReadable(), true);
61        $this->assertEquals($b->isSeekable(), true);
62        $this->assertEquals($b->read(3), 'foo');
63        $this->assertEquals($b->tell(), 3);
64        $this->assertEquals($a->tell(), 3);
65        $this->assertEmpty($b->read(1));
66        $this->assertEquals($b->eof(), true);
67        $this->assertEquals($a->eof(), true);
68        $b->seek(0);
69        $this->assertEquals('foo', (string) $b);
70        $b->seek(0);
71        $this->assertEquals('foo', $b->getContents());
72        $this->assertEquals($a->getMetadata(), $b->getMetadata());
73        $b->seek(0, SEEK_END);
74        $b->write('bar');
75        $this->assertEquals('foobar', (string) $b);
76        $this->assertIsResource($b->detach());
77        $b->close();
78    }
79
80    public function testDecoratesWithCustomizations()
81    {
82        $called = false;
83        $a = Stream::factory('foo');
84        $b = FnStream::decorate($a, [
85            'read' => function ($len) use (&$called, $a) {
86                $called = true;
87                return $a->read($len);
88            }
89        ]);
90        $this->assertEquals('foo', $b->read(3));
91        $this->assertTrue($called);
92    }
93}
94