1<?php
2namespace GuzzleHttp\Tests\Stream;
3
4use GuzzleHttp\Stream\Stream;
5use GuzzleHttp\Stream\FnStream;
6
7/**
8 * @covers GuzzleHttp\Stream\FnStream
9 */
10class FnStreamTest extends \PHPUnit_Framework_TestCase
11{
12    /**
13     * @expectedException \BadMethodCallException
14     * @expectedExceptionMessage seek() is not implemented in the FnStream
15     */
16    public function testThrowsWhenNotImplemented()
17    {
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    public function testDoesNotRequireClose()
46    {
47        $s = new FnStream([]);
48        unset($s);
49    }
50
51    public function testDecoratesStream()
52    {
53        $a = Stream::factory('foo');
54        $b = FnStream::decorate($a, []);
55        $this->assertEquals(3, $b->getSize());
56        $this->assertEquals($b->isWritable(), true);
57        $this->assertEquals($b->isReadable(), true);
58        $this->assertEquals($b->isSeekable(), true);
59        $this->assertEquals($b->read(3), 'foo');
60        $this->assertEquals($b->tell(), 3);
61        $this->assertEquals($a->tell(), 3);
62        $this->assertEmpty($b->read(1));
63        $this->assertEquals($b->eof(), true);
64        $this->assertEquals($a->eof(), true);
65        $b->seek(0);
66        $this->assertEquals('foo', (string) $b);
67        $b->seek(0);
68        $this->assertEquals('foo', $b->getContents());
69        $this->assertEquals($a->getMetadata(), $b->getMetadata());
70        $b->seek(0, SEEK_END);
71        $b->write('bar');
72        $this->assertEquals('foobar', (string) $b);
73        $this->assertInternalType('resource', $b->detach());
74        $b->close();
75    }
76
77    public function testDecoratesWithCustomizations()
78    {
79        $called = false;
80        $a = Stream::factory('foo');
81        $b = FnStream::decorate($a, [
82            'read' => function ($len) use (&$called, $a) {
83                $called = true;
84                return $a->read($len);
85            }
86        ]);
87        $this->assertEquals('foo', $b->read(3));
88        $this->assertTrue($called);
89    }
90}
91