Browse Source

Add tests for classes in the Predis\Protocol\Text namespace.

This was the only namespace containing classes with no tests.
Daniele Alessandri 12 years ago
parent
commit
6e76ea6c7e

+ 2 - 2
lib/Predis/Protocol/Text/ResponseBulkHandler.php

@@ -36,9 +36,9 @@ class ResponseBulkHandler implements ResponseHandlerInterface
     {
         $length = (int) $lengthString;
 
-        if ($length != $lengthString) {
+        if ("$length" !== $lengthString) {
             Helpers::onCommunicationException(new ProtocolException(
-                $connection, "Cannot parse '$length' as data length"
+                $connection, "Cannot parse '$lengthString' as bulk length"
             ));
         }
 

+ 1 - 1
lib/Predis/Protocol/Text/ResponseErrorHandler.php

@@ -25,7 +25,7 @@ use Predis\Protocol\ResponseHandlerInterface;
  * @link http://redis.io/topics/protocol
  * @author Daniele Alessandri <suppakilla@gmail.com>
  */
-class ResponseErrorSilentHandler implements ResponseHandlerInterface
+class ResponseErrorHandler implements ResponseHandlerInterface
 {
     /**
      * {@inheritdoc}

+ 2 - 2
lib/Predis/Protocol/Text/ResponseMultiBulkHandler.php

@@ -36,9 +36,9 @@ class ResponseMultiBulkHandler implements ResponseHandlerInterface
     {
         $length = (int) $lengthString;
 
-        if ($length != $lengthString) {
+        if ("$length" !== $lengthString) {
             Helpers::onCommunicationException(new ProtocolException(
-                $connection, "Cannot parse '$length' as data length"
+                $connection, "Cannot parse '$lengthString' as multi-bulk length"
             ));
         }
 

+ 2 - 2
lib/Predis/Protocol/Text/ResponseMultiBulkStreamHandler.php

@@ -37,9 +37,9 @@ class ResponseMultiBulkStreamHandler implements ResponseHandlerInterface
     {
         $length = (int) $lengthString;
 
-        if ($length != $lengthString) {
+        if ("$length" != $lengthString) {
             Helpers::onCommunicationException(new ProtocolException(
-                $connection, "Cannot parse '$length' as data length"
+                $connection, "Cannot parse '$lengthString' as multi-bulk length"
             ));
         }
 

+ 1 - 1
lib/Predis/Protocol/Text/TextResponseReader.php

@@ -91,7 +91,7 @@ class TextResponseReader implements ResponseReaderInterface
         $prefix = $header[0];
 
         if (!isset($this->handlers[$prefix])) {
-            $this->protocolError($connection, "Unknown prefix '$prefix'");
+            $this->protocolError($connection, "Unknown prefix: '$prefix'");
         }
 
         $handler = $this->handlers[$prefix];

+ 119 - 0
tests/Predis/Protocol/Text/ComposableTextProtocolTest.php

@@ -0,0 +1,119 @@
+<?php
+
+/*
+ * This file is part of the Predis package.
+ *
+ * (c) Daniele Alessandri <suppakilla@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Predis\Protocol\Text;
+
+use \PHPUnit_Framework_TestCase as StandardTestCase;
+
+/**
+ *
+ */
+class ComposableTextProtocolTest extends StandardTestCase
+{
+    /**
+     * @group disconnected
+     */
+    public function testCustomSerializer()
+    {
+        $serializer = $this->getMock('Predis\Protocol\CommandSerializerInterface');
+
+        $protocol = new ComposableTextProtocol();
+        $protocol->setSerializer($serializer);
+
+        $this->assertSame($serializer, $protocol->getSerializer());
+    }
+
+    /**
+     * @group disconnected
+     */
+    public function testCustomReader()
+    {
+        $reader = $this->getMock('Predis\Protocol\ResponseReaderInterface');
+
+        $protocol = new ComposableTextProtocol();
+        $protocol->setReader($reader);
+
+        $this->assertSame($reader, $protocol->getReader());
+    }
+
+    /**
+     * @group disconnected
+     */
+    public function testConnectionWrite()
+    {
+        $serialized = "*1\r\n$4\r\nPING\r\n";
+
+        $command = $this->getMock('Predis\Command\CommandInterface');
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+        $serializer = $this->getMock('Predis\Protocol\CommandSerializerInterface');
+
+        $protocol = new ComposableTextProtocol();
+        $protocol->setSerializer($serializer);
+
+        $connection->expects($this->once())
+                   ->method('writeBytes')
+                   ->with($this->equalTo($serialized));
+
+        $serializer->expects($this->once())
+                   ->method('serialize')
+                   ->with($command)
+                   ->will($this->returnValue($serialized));
+
+        $protocol->write($connection, $command);
+    }
+
+    /**
+     * @group disconnected
+     */
+    public function testConnectionRead()
+    {
+        $serialized = "*1\r\n$4\r\nPING\r\n";
+
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+        $reader = $this->getMock('Predis\Protocol\ResponseReaderInterface');
+
+        $protocol = new ComposableTextProtocol();
+        $protocol->setReader($reader);
+
+        $reader->expects($this->once())
+                   ->method('read')
+                   ->with($connection)
+                   ->will($this->returnValue('bulk'));
+
+        $this->assertSame('bulk', $protocol->read($connection));
+    }
+
+    /**
+     * @group disconnected
+     */
+    public function testSetMultibulkOption()
+    {
+        $protocol = new ComposableTextProtocol();
+        $reader = $protocol->getReader();
+
+        $protocol->setOption('iterable_multibulk', true);
+        $this->assertInstanceOf('Predis\Protocol\Text\ResponseMultiBulkStreamHandler', $reader->getHandler('*'));
+
+        $protocol->setOption('iterable_multibulk', false);
+        $this->assertInstanceOf('Predis\Protocol\Text\ResponseMultiBulkHandler', $reader->getHandler('*'));
+    }
+
+    /**
+     * @group disconnected
+     * @expectedException InvalidArgumentException
+     * @expectedExceptionMessage The option unknown_option is not supported by the current protocol
+     */
+    public function testSetInvalidOption()
+    {
+        $protocol = new ComposableTextProtocol();
+        $protocol->setOption('unknown_option', true);
+    }
+}

+ 91 - 0
tests/Predis/Protocol/Text/ResponseBulkHandlerTest.php

@@ -0,0 +1,91 @@
+<?php
+
+/*
+ * This file is part of the Predis package.
+ *
+ * (c) Daniele Alessandri <suppakilla@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Predis\Protocol\Text;
+
+use \PHPUnit_Framework_TestCase as StandardTestCase;
+
+/**
+ *
+ */
+class ResponseBulkHandlerTest extends StandardTestCase
+{
+    /**
+     * @group disconnected
+     */
+    public function testZeroLengthBulk()
+    {
+        $handler = new ResponseBulkHandler();
+
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+
+        $connection->expects($this->never())->method('readLine');
+        $connection->expects($this->once())
+                   ->method('readBytes')
+                   ->with($this->equalTo(2))
+                   ->will($this->returnValue("\r\n"));
+
+        $this->assertSame('', $handler->handle($connection, '0'));
+    }
+
+    /**
+     * @group disconnected
+     */
+    public function testBulk()
+    {
+        $bulk = "This is a bulk string.";
+        $bulkLengh = (string) strlen($bulk);
+
+        $handler = new ResponseBulkHandler();
+
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+
+        $connection->expects($this->never())->method('readLine');
+        $connection->expects($this->once())
+                   ->method('readBytes')
+                   ->with($this->equalTo($bulkLengh + 2))
+                   ->will($this->returnValue("$bulk\r\n"));
+
+        $this->assertSame($bulk, $handler->handle($connection, $bulkLengh));
+    }
+
+    /**
+     * @group disconnected
+     */
+    public function testNull()
+    {
+        $handler = new ResponseBulkHandler();
+
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+
+        $connection->expects($this->never())->method('readLine');
+        $connection->expects($this->never())->method('readBytes');
+
+        $this->assertNull($handler->handle($connection, '-1'));
+    }
+
+    /**
+     * @group disconnected
+     * @expectedException Predis\Protocol\ProtocolException
+     * @expectedExceptionMessage Cannot parse 'invalid' as bulk length
+     */
+    public function testInvalidLength()
+    {
+        $handler = new ResponseBulkHandler();
+
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+
+        $connection->expects($this->never())->method('readLine');
+        $connection->expects($this->never())->method('readBytes');
+
+        $handler->handle($connection, 'invalid');
+    }
+}

+ 39 - 0
tests/Predis/Protocol/Text/ResponseErrorHandlerTest.php

@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * This file is part of the Predis package.
+ *
+ * (c) Daniele Alessandri <suppakilla@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Predis\Protocol\Text;
+
+use \PHPUnit_Framework_TestCase as StandardTestCase;
+
+/**
+ *
+ */
+class ResponseErrorHandlerTest extends StandardTestCase
+{
+    /**
+     * @group disconnected
+     */
+    public function testOk()
+    {
+        $handler = new ResponseErrorHandler();
+
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+
+        $connection->expects($this->never())->method('readLine');
+        $connection->expects($this->never())->method('readBytes');
+
+        $message = "ERR Operation against a key holding the wrong kind of value";
+        $response = $handler->handle($connection, $message);
+
+        $this->assertInstanceOf('Predis\ResponseError', $response);
+        $this->assertSame($message, $response->getMessage());
+    }
+}

+ 71 - 0
tests/Predis/Protocol/Text/ResponseIntegerHandlerTest.php

@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * This file is part of the Predis package.
+ *
+ * (c) Daniele Alessandri <suppakilla@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Predis\Protocol\Text;
+
+use \PHPUnit_Framework_TestCase as StandardTestCase;
+use Predis\ResponseQueued;
+
+/**
+ *
+ */
+class ResponseIntegerHandlerTest extends StandardTestCase
+{
+    /**
+     * @group disconnected
+     */
+    public function testInteger()
+    {
+        $handler = new ResponseIntegerHandler();
+
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+
+        $connection->expects($this->never())->method('readLine');
+        $connection->expects($this->never())->method('readBytes');
+
+        $this->assertSame(0, $handler->handle($connection, '0'));
+        $this->assertSame(1, $handler->handle($connection, '1'));
+        $this->assertSame(10, $handler->handle($connection, '10'));
+        $this->assertSame(-10, $handler->handle($connection, '-10'));
+    }
+
+    /**
+     * @group disconnected
+     */
+    public function testNull()
+    {
+        $handler = new ResponseIntegerHandler();
+
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+
+        $connection->expects($this->never())->method('readLine');
+        $connection->expects($this->never())->method('readBytes');
+
+        $this->assertNull($handler->handle($connection, 'nil'));
+    }
+
+    /**
+     * @group disconnected
+     * @expectedException Predis\Protocol\ProtocolException
+     * @expectedExceptionMessage Cannot parse 'invalid' as numeric response
+     */
+    public function testInvalid()
+    {
+        $handler = new ResponseIntegerHandler();
+
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+
+        $connection->expects($this->never())->method('readLine');
+        $connection->expects($this->never())->method('readBytes');
+
+        $handler->handle($connection, 'invalid');
+    }
+}

+ 84 - 0
tests/Predis/Protocol/Text/ResponseMultiBulkHandlerTest.php

@@ -0,0 +1,84 @@
+<?php
+
+/*
+ * This file is part of the Predis package.
+ *
+ * (c) Daniele Alessandri <suppakilla@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Predis\Protocol\Text;
+
+use \PHPUnit_Framework_TestCase as StandardTestCase;
+
+/**
+ *
+ */
+class ResponseMultiBulkHandlerTest extends StandardTestCase
+{
+    /**
+     * @group disconnected
+     */
+    public function testMultiBulk()
+    {
+        $handler = new ResponseMultiBulkHandler();
+
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+
+        $connection->expects($this->once())
+                   ->method('getProtocol')
+                   ->will($this->returnValue(new ComposableTextProtocol()));
+
+        $connection->expects($this->at(1))
+                   ->method('readLine')
+                   ->will($this->returnValue("$3"));
+
+        $connection->expects($this->at(2))
+                   ->method('readBytes')
+                   ->will($this->returnValue("foo\r\n"));
+
+        $connection->expects($this->at(3))
+                   ->method('readLine')
+                   ->will($this->returnValue("$3"));
+
+        $connection->expects($this->at(4))
+                   ->method('readBytes')
+                   ->will($this->returnValue("bar\r\n"));
+
+        $this->assertSame(array('foo', 'bar'), $handler->handle($connection, '2'));
+    }
+
+    /**
+     * @group disconnected
+     */
+    public function testNull()
+    {
+        $handler = new ResponseMultiBulkHandler();
+
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+
+        $connection->expects($this->never())->method('readLine');
+        $connection->expects($this->never())->method('readBytes');
+
+        $this->assertNull($handler->handle($connection, '-1'));
+    }
+
+    /**
+     * @group disconnected
+     * @expectedException Predis\Protocol\ProtocolException
+     * @expectedExceptionMessage Cannot parse 'invalid' as multi-bulk length
+     */
+    public function testInvalid()
+    {
+        $handler = new ResponseMultiBulkHandler();
+
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+
+        $connection->expects($this->never())->method('readLine');
+        $connection->expects($this->never())->method('readBytes');
+
+        $handler->handle($connection, 'invalid');
+    }
+}

+ 52 - 0
tests/Predis/Protocol/Text/ResponseMultiBulkStreamHandlerTest.php

@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of the Predis package.
+ *
+ * (c) Daniele Alessandri <suppakilla@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Predis\Protocol\Text;
+
+use \PHPUnit_Framework_TestCase as StandardTestCase;
+
+/**
+ *
+ */
+class ResponseMultiBulkStreamHandlerTest extends StandardTestCase
+{
+    /**
+     * @group disconnected
+     */
+    public function testOk()
+    {
+        $handler = new ResponseMultiBulkStreamHandler();
+
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+
+        $connection->expects($this->never())->method('readLine');
+        $connection->expects($this->never())->method('readBytes');
+
+        $this->assertInstanceOf('Predis\Iterator\MultiBulkResponseSimple', $handler->handle($connection, '1'));
+    }
+
+    /**
+     * @group disconnected
+     * @expectedException Predis\Protocol\ProtocolException
+     * @expectedExceptionMessage Cannot parse 'invalid' as multi-bulk length
+     */
+    public function testInvalid()
+    {
+        $handler = new ResponseMultiBulkStreamHandler();
+
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+
+        $connection->expects($this->never())->method('readLine');
+        $connection->expects($this->never())->method('readBytes');
+
+        $handler->handle($connection, 'invalid');
+    }
+}

+ 66 - 0
tests/Predis/Protocol/Text/ResponseStatusHandlerTest.php

@@ -0,0 +1,66 @@
+<?php
+
+/*
+ * This file is part of the Predis package.
+ *
+ * (c) Daniele Alessandri <suppakilla@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Predis\Protocol\Text;
+
+use \PHPUnit_Framework_TestCase as StandardTestCase;
+use Predis\ResponseQueued;
+
+/**
+ *
+ */
+class ResponseStatusHandlerTest extends StandardTestCase
+{
+    /**
+     * @group disconnected
+     */
+    public function testOk()
+    {
+        $handler = new ResponseStatusHandler();
+
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+
+        $connection->expects($this->never())->method('readLine');
+        $connection->expects($this->never())->method('readBytes');
+
+        $this->assertTrue($handler->handle($connection, 'OK'));
+    }
+
+    /**
+     * @group disconnected
+     */
+    public function testQueued()
+    {
+        $handler = new ResponseStatusHandler();
+
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+
+        $connection->expects($this->never())->method('readLine');
+        $connection->expects($this->never())->method('readBytes');
+
+        $this->assertInstanceOf('Predis\ResponseQueued', $handler->handle($connection, 'QUEUED'));
+    }
+
+    /**
+     * @group disconnected
+     */
+    public function testPlainString()
+    {
+        $handler = new ResponseStatusHandler();
+
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+
+        $connection->expects($this->never())->method('readLine');
+        $connection->expects($this->never())->method('readBytes');
+
+        $this->assertSame('Background saving started', $handler->handle($connection, 'Background saving started'));
+    }
+}

+ 64 - 0
tests/Predis/Protocol/Text/TextCommandSerializerTest.php

@@ -0,0 +1,64 @@
+<?php
+
+/*
+ * This file is part of the Predis package.
+ *
+ * (c) Daniele Alessandri <suppakilla@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Predis\Protocol\Text;
+
+use \PHPUnit_Framework_TestCase as StandardTestCase;
+
+/**
+ *
+ */
+class TextCommandSerializerTest extends StandardTestCase
+{
+    /**
+     * @group disconnected
+     */
+    public function testSerializerIdWithNoArguments()
+    {
+        $serializer = new TextCommandSerializer();
+
+        $command = $this->getMock('Predis\Command\CommandInterface');
+
+        $command->expects($this->once())
+                ->method('getId')
+                ->will($this->returnValue('PING'));
+
+        $command->expects($this->once())
+                ->method('getArguments')
+                ->will($this->returnValue(array()));
+
+        $result = $serializer->serialize($command);
+
+        $this->assertSame("*1\r\n$4\r\nPING\r\n", $result);
+    }
+
+    /**
+     * @group disconnected
+     */
+    public function testSerializerIdWithArguments()
+    {
+        $serializer = new TextCommandSerializer();
+
+        $command = $this->getMock('Predis\Command\CommandInterface');
+
+        $command->expects($this->once())
+                ->method('getId')
+                ->will($this->returnValue('SET'));
+
+        $command->expects($this->once())
+                ->method('getArguments')
+                ->will($this->returnValue(array('key', 'value')));
+
+        $result = $serializer->serialize($command);
+
+        $this->assertSame("*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue\r\n", $result);
+    }
+}

+ 120 - 0
tests/Predis/Protocol/Text/TextProtocolTest.php

@@ -0,0 +1,120 @@
+<?php
+
+/*
+ * This file is part of the Predis package.
+ *
+ * (c) Daniele Alessandri <suppakilla@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Predis\Protocol\Text;
+
+use \PHPUnit_Framework_TestCase as StandardTestCase;
+
+/**
+ *
+ */
+class TextProtocolTest extends StandardTestCase
+{
+    /**
+     * @group disconnected
+     */
+    public function testConnectionWrite()
+    {
+        $serialized = "*1\r\n$4\r\nPING\r\n";
+        $protocol = new TextProtocol();
+
+        $command = $this->getMock('Predis\Command\CommandInterface');
+
+        $command->expects($this->once())
+                ->method('getId')
+                ->will($this->returnValue('PING'));
+
+        $command->expects($this->once())
+                ->method('getArguments')
+                ->will($this->returnValue(array()));
+
+
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+
+        $connection->expects($this->once())
+                   ->method('writeBytes')
+                   ->with($this->equalTo($serialized));
+
+        $protocol->write($connection, $command);
+    }
+
+    /**
+     * @todo Improve test coverage
+     * @group disconnected
+     */
+    public function testConnectionRead()
+    {
+        $protocol = new TextProtocol();
+
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+
+        $connection->expects($this->at(0))
+                   ->method('readLine')
+                   ->will($this->returnValue("+OK"));
+
+        $connection->expects($this->at(1))
+                   ->method('readLine')
+                   ->will($this->returnValue("-ERR error message"));
+
+        $connection->expects($this->at(2))
+                   ->method('readLine')
+                   ->will($this->returnValue(":2"));
+
+        $connection->expects($this->at(3))
+                   ->method('readLine')
+                   ->will($this->returnValue("$-1"));
+
+        $connection->expects($this->at(4))
+                   ->method('readLine')
+                   ->will($this->returnValue("*-1"));
+
+        $this->assertTrue($protocol->read($connection));
+        $this->assertEquals("ERR error message", $protocol->read($connection));
+        $this->assertSame(2, $protocol->read($connection));
+        $this->assertNull($protocol->read($connection));
+        $this->assertNull($protocol->read($connection));
+    }
+
+    /**
+     * @group disconnected
+     */
+    public function testIterableMultibulkSupport()
+    {
+        $protocol = new TextProtocol();
+        $protocol->setOption('iterable_multibulk', true);
+
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+
+        $connection->expects($this->once(4))
+                   ->method('readLine')
+                   ->will($this->returnValue("*1"));
+
+        $this->assertInstanceOf('Predis\Iterator\MultiBulkResponseSimple', $protocol->read($connection));
+    }
+
+    /**
+     * @group disconnected
+     * @expectedException Predis\Protocol\ProtocolException
+     * @expectedExceptionMessage Unknown prefix: '!'
+     */
+    public function testUnknownResponsePrefix()
+    {
+        $protocol = new TextProtocol();
+
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+
+        $connection->expects($this->once())
+                   ->method('readLine')
+                   ->will($this->returnValue('!'));
+
+        $protocol->read($connection);
+    }
+}

+ 123 - 0
tests/Predis/Protocol/Text/TextResponseReaderTest.php

@@ -0,0 +1,123 @@
+<?php
+
+/*
+ * This file is part of the Predis package.
+ *
+ * (c) Daniele Alessandri <suppakilla@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Predis\Protocol\Text;
+
+use \PHPUnit_Framework_TestCase as StandardTestCase;
+
+/**
+ *
+ */
+class TextResponseReaderTest extends StandardTestCase
+{
+    /**
+     * @group disconnected
+     */
+    public function testDefaultHandlers()
+    {
+        $reader = new TextResponseReader();
+
+        $this->assertInstanceOf('Predis\Protocol\Text\ResponseStatusHandler', $reader->getHandler('+'));
+        $this->assertInstanceOf('Predis\Protocol\Text\ResponseErrorHandler', $reader->getHandler('-'));
+        $this->assertInstanceOf('Predis\Protocol\Text\ResponseIntegerHandler', $reader->getHandler(':'));
+        $this->assertInstanceOf('Predis\Protocol\Text\ResponseBulkHandler', $reader->getHandler('$'));
+        $this->assertInstanceOf('Predis\Protocol\Text\ResponseMultiBulkHandler', $reader->getHandler('*'));
+
+        $this->assertNull($reader->getHandler('!'));
+    }
+
+    /**
+     * @group disconnected
+     */
+    public function testReplaceHandler()
+    {
+        $handler = $this->getMock('Predis\Protocol\ResponseHandlerInterface');
+
+        $reader = new TextResponseReader();
+        $reader->setHandler('+', $handler);
+
+        $this->assertSame($handler, $reader->getHandler('+'));
+    }
+
+    /**
+     * @group disconnected
+     */
+    public function testReadResponse()
+    {
+        $reader = new TextResponseReader();
+
+        $protocol = new ComposableTextProtocol();
+        $protocol->setReader($reader);
+
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+
+        $connection->expects($this->at(0))
+                   ->method('readLine')
+                   ->will($this->returnValue("+OK"));
+
+        $connection->expects($this->at(1))
+                   ->method('readLine')
+                   ->will($this->returnValue("-ERR error message"));
+
+        $connection->expects($this->at(2))
+                   ->method('readLine')
+                   ->will($this->returnValue(":2"));
+
+        $connection->expects($this->at(3))
+                   ->method('readLine')
+                   ->will($this->returnValue("$-1"));
+
+        $connection->expects($this->at(4))
+                   ->method('readLine')
+                   ->will($this->returnValue("*-1"));
+
+        $this->assertTrue($reader->read($connection));
+        $this->assertEquals("ERR error message", $reader->read($connection));
+        $this->assertSame(2, $reader->read($connection));
+        $this->assertNull($reader->read($connection));
+        $this->assertNull($reader->read($connection));
+    }
+
+    /**
+     * @group disconnected
+     * @expectedException Predis\Protocol\ProtocolException
+     * @expectedExceptionMessage Unexpected empty header
+     */
+    public function testEmptyResponseHeader()
+    {
+        $reader = new TextResponseReader();
+
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+
+        $connection->expects($this->once())
+                   ->method('readLine')
+                   ->will($this->returnValue(''));
+
+        $reader->read($connection);
+    }
+    /**
+     * @group disconnected
+     * @expectedException Predis\Protocol\ProtocolException
+     * @expectedExceptionMessage Unknown prefix: '!'
+     */
+    public function testUnknownResponsePrefix()
+    {
+        $reader = new TextResponseReader();
+
+        $connection = $this->getMock('Predis\Connection\ComposableConnectionInterface');
+
+        $connection->expects($this->once())
+                   ->method('readLine')
+                   ->will($this->returnValue('!'));
+
+        $reader->read($connection);
+    }
+}