Clean up MessageTest and documentation for Message classes
This commit is contained in:
parent
b82ebf6d95
commit
72d5df244d
|
|
@ -15,20 +15,19 @@ abstract class Message implements MessageInterface
|
|||
/** @var StreamInterface */
|
||||
protected $body;
|
||||
/** @var string */
|
||||
protected $protocolVersion = "1.1";
|
||||
protected $protocolVersion = '1.1';
|
||||
|
||||
/**
|
||||
* Create a new Message, optionally with headers and a body.
|
||||
*
|
||||
* If provided, $headers MUST by an associative array with header field
|
||||
* names as (string) keys and lists of header field values (string[])
|
||||
* as values.
|
||||
* $headers is an optional associative array with header field names as
|
||||
* (string) keys and lists of header field values (string[]) as values.
|
||||
*
|
||||
* If no StreamInterface is provided for $body, the instance will create
|
||||
* a NullStream instance for the message body.
|
||||
*
|
||||
* @param array $headers Associative array of headers fields with header
|
||||
* field names as keys and list arrays of field values as values
|
||||
* @param array $headers Associative array with header field names as
|
||||
* (string) keys and lists of header field values (string[]) as values.
|
||||
* @param StreamInterface $body A stream representation of the message
|
||||
* entity body
|
||||
*/
|
||||
|
|
@ -61,8 +60,6 @@ abstract class Message implements MessageInterface
|
|||
/**
|
||||
* Retrieves the HTTP protocol version as a string.
|
||||
*
|
||||
* The string MUST contain only the HTTP version number (e.g., "1.1", "1.0").
|
||||
*
|
||||
* @return string HTTP protocol version.
|
||||
*/
|
||||
public function getProtocolVersion()
|
||||
|
|
@ -73,9 +70,6 @@ abstract class Message implements MessageInterface
|
|||
/**
|
||||
* Create a new instance with the specified HTTP protocol version.
|
||||
*
|
||||
* The version string MUST contain only the HTTP version number (e.g.,
|
||||
* "1.1", "1.0").
|
||||
*
|
||||
* @param string $version HTTP protocol version
|
||||
* @return static
|
||||
*/
|
||||
|
|
@ -94,7 +88,7 @@ abstract class Message implements MessageInterface
|
|||
*
|
||||
* // Represent the headers as a string
|
||||
* foreach ($message->getHeaders() as $name => $values) {
|
||||
* echo $name . ": " . implode(", ", $values);
|
||||
* echo $name . ': ' . implode(', ', $values);
|
||||
* }
|
||||
*
|
||||
* // Emit headers iteratively:
|
||||
|
|
@ -177,9 +171,9 @@ abstract class Message implements MessageInterface
|
|||
public function getHeaderLine($name)
|
||||
{
|
||||
if (isset($this->headers[$name])) {
|
||||
return join(", ", $this->headers[$name]);
|
||||
return join(', ', $this->headers[$name]);
|
||||
} else {
|
||||
return "";
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -278,7 +272,7 @@ abstract class Message implements MessageInterface
|
|||
};
|
||||
|
||||
if (!is_string($name)) {
|
||||
throw new \InvalidArgumentException("Header name must be a string");
|
||||
throw new \InvalidArgumentException('Header name must be a string');
|
||||
}
|
||||
|
||||
if ($is_allowed($value)) {
|
||||
|
|
@ -286,7 +280,7 @@ abstract class Message implements MessageInterface
|
|||
} elseif (is_array($value) && count($value) === count(array_filter($value, $is_allowed))) {
|
||||
return $value;
|
||||
} else {
|
||||
throw new \InvalidArgumentException("Header values must be a string or string[]");
|
||||
throw new \InvalidArgumentException('Header values must be a string or string[]');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,32 +2,45 @@
|
|||
|
||||
namespace WellRESTed\Test\Unit\Message;
|
||||
|
||||
use WellRESTed\Message\Message;
|
||||
use WellRESTed\Message\Response;
|
||||
use WellRESTed\Message\Stream;
|
||||
use WellRESTed\Test\TestCase;
|
||||
|
||||
class MessageTest extends TestCase
|
||||
{
|
||||
/** @var Message */
|
||||
private $message;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->message = new Response();
|
||||
}
|
||||
|
||||
public function testSetsHeadersOnConstruction()
|
||||
{
|
||||
$headers = ["X-foo" => ["bar", "baz"]];
|
||||
$body = null;
|
||||
$message = $this->getMockForAbstractClass('\WellRESTed\Message\Message', [$headers, $body]);
|
||||
$this->assertEquals(["bar", "baz"], $message->getHeader("X-foo"));
|
||||
$headers = ['X-foo' => ['bar', 'baz']];
|
||||
$message = new Response(200, $headers);
|
||||
$this->assertEquals(['bar', 'baz'], $message->getHeader('X-foo'));
|
||||
}
|
||||
|
||||
public function testSetsBodyOnConstruction()
|
||||
{
|
||||
$headers = null;
|
||||
$body = $this->prophesize('\Psr\Http\Message\StreamInterface');
|
||||
$message = $this->getMockForAbstractClass('\WellRESTed\Message\Message', [$headers, $body->reveal()]);
|
||||
$this->assertSame($body->reveal(), $message->getBody());
|
||||
$body = new Stream('Hello, world');
|
||||
$message = new Response(200, [], $body);
|
||||
$this->assertSame($body, $message->getBody());
|
||||
}
|
||||
|
||||
public function testCloneMakesDeepCopyOfHeaders()
|
||||
public function testCloneMakesDeepCopyOfHeaders()
|
||||
{
|
||||
$message1 = $this->getMockForAbstractClass('\WellRESTed\Message\Message');
|
||||
$message1 = $message1->withHeader("Content-type", "text/plain");
|
||||
$message2 = $message1->withHeader("Content-type", "application/json");
|
||||
$this->assertNotEquals($message1->getHeader("Content-type"), $message2->getHeader("Content-type"));
|
||||
$message1 = (new Response())
|
||||
->withHeader('Content-type', 'text/plain');
|
||||
$message2 = $message1
|
||||
->withHeader('Content-type', 'application/json');
|
||||
|
||||
$this->assertNotEquals(
|
||||
$message1->getHeader('Content-type'),
|
||||
$message2->getHeader('Content-type'));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
|
@ -35,22 +48,22 @@ class MessageTest extends TestCase
|
|||
|
||||
public function testGetProtocolVersionReturnsProtocolVersion1Point1ByDefault()
|
||||
{
|
||||
$message = $this->getMockForAbstractClass('\WellRESTed\Message\Message');
|
||||
$this->assertEquals("1.1", $message->getProtocolVersion());
|
||||
$message = new Response();
|
||||
$this->assertEquals('1.1', $message->getProtocolVersion());
|
||||
}
|
||||
|
||||
public function testGetProtocolVersionReturnsProtocolVersion()
|
||||
{
|
||||
$message = $this->getMockForAbstractClass('\WellRESTed\Message\Message');
|
||||
$message = $message->withProtocolVersion("1.0");
|
||||
$this->assertEquals("1.0", $message->getProtocolVersion());
|
||||
$message = (new Response())
|
||||
->withProtocolVersion('1.0');
|
||||
$this->assertEquals('1.0', $message->getProtocolVersion());
|
||||
}
|
||||
|
||||
public function testGetProtocolVersionReplacesProtocolVersion()
|
||||
{
|
||||
$message = $this->getMockForAbstractClass('\WellRESTed\Message\Message');
|
||||
$message = $message->withProtocolVersion("1.0");
|
||||
$this->assertEquals("1.0", $message->getProtocolVersion());
|
||||
$message = (new Response())
|
||||
->withProtocolVersion('1.0');
|
||||
$this->assertEquals('1.0', $message->getProtocolVersion());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
|
@ -59,17 +72,17 @@ class MessageTest extends TestCase
|
|||
/** @dataProvider validHeaderValueProvider */
|
||||
public function testWithHeaderReplacesHeader($expected, $value)
|
||||
{
|
||||
$message = $this->getMockForAbstractClass('\WellRESTed\Message\Message');
|
||||
$message = $message->withHeader("X-foo", "Original value");
|
||||
$message = $message->withHeader("X-foo", $value);
|
||||
$this->assertEquals($expected, $message->getHeader("X-foo"));
|
||||
$message = (new Response())
|
||||
->withHeader('X-foo', 'Original value')
|
||||
->withHeader('X-foo', $value);
|
||||
$this->assertEquals($expected, $message->getHeader('X-foo'));
|
||||
}
|
||||
|
||||
public function validHeaderValueProvider()
|
||||
{
|
||||
return [
|
||||
[["0"], 0],
|
||||
[["molly","bear"],["molly","bear"]]
|
||||
[['0'], 0],
|
||||
[['molly','bear'],['molly','bear']]
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -79,114 +92,118 @@ class MessageTest extends TestCase
|
|||
*/
|
||||
public function testWithHeaderThrowsExceptionWithInvalidArgument($name, $value)
|
||||
{
|
||||
$message = $this->getMockForAbstractClass('\WellRESTed\Message\Message');
|
||||
$message->withHeader($name, $value);
|
||||
$message = (new Response())
|
||||
->withHeader($name, $value);
|
||||
}
|
||||
|
||||
public function invalidHeaderProvider()
|
||||
{
|
||||
return [
|
||||
[0, 1024],
|
||||
["Content-length", false],
|
||||
["Content-length", [false]]
|
||||
['Content-length', false],
|
||||
['Content-length', [false]]
|
||||
];
|
||||
}
|
||||
|
||||
public function testWithAddedHeaderSetsHeader()
|
||||
{
|
||||
$message = $this->getMockForAbstractClass('\WellRESTed\Message\Message');
|
||||
$message = $message->withAddedHeader("Content-type", "application/json");
|
||||
$this->assertEquals(["application/json"], $message->getHeader("Content-type"));
|
||||
$message = (new Response())
|
||||
->withAddedHeader('Content-type', 'application/json');
|
||||
$this->assertEquals(['application/json'], $message->getHeader('Content-type'));
|
||||
}
|
||||
|
||||
public function testWithAddedHeaderAppendsValue()
|
||||
{
|
||||
$message = $this->getMockForAbstractClass('\WellRESTed\Message\Message');
|
||||
$message = $message->withAddedHeader("Set-Cookie", ["cat=Molly"]);
|
||||
$message = $message->withAddedHeader("Set-Cookie", ["dog=Bear"]);
|
||||
$cookies = $message->getHeader("Set-Cookie");
|
||||
$this->assertTrue(in_array("cat=Molly", $cookies) && in_array("dog=Bear", $cookies));
|
||||
$message = (new Response())
|
||||
->withAddedHeader('Set-Cookie', ['cat=Molly'])
|
||||
->withAddedHeader('Set-Cookie', ['dog=Bear']);
|
||||
$cookies = $message->getHeader('Set-Cookie');
|
||||
$this->assertTrue(
|
||||
in_array('cat=Molly', $cookies) &&
|
||||
in_array('dog=Bear', $cookies));
|
||||
}
|
||||
|
||||
public function testWithoutHeaderRemovesHeader()
|
||||
{
|
||||
$message = $this->getMockForAbstractClass('\WellRESTed\Message\Message');
|
||||
$message = $message->withHeader("Content-type", "application/json");
|
||||
$message = $message->withoutHeader("Content-type");
|
||||
$this->assertFalse($message->hasHeader("Content-type"));
|
||||
$message = (new Response())
|
||||
->withHeader('Content-type', 'application/json')
|
||||
->withoutHeader('Content-type');
|
||||
$this->assertFalse($message->hasHeader('Content-type'));
|
||||
}
|
||||
|
||||
public function testGetHeaderReturnsEmptyArrayForUnsetHeader()
|
||||
{
|
||||
$message = $this->getMockForAbstractClass('\WellRESTed\Message\Message');
|
||||
$this->assertEquals([], $message->getHeader("X-name"));
|
||||
$message = new Response();
|
||||
$this->assertEquals([], $message->getHeader('X-name'));
|
||||
}
|
||||
|
||||
public function testGetHeaderReturnsSingleHeader()
|
||||
{
|
||||
$message = $this->getMockForAbstractClass('\WellRESTed\Message\Message');
|
||||
$message = $message->withAddedHeader("Content-type", "application/json");
|
||||
$this->assertEquals(["application/json"], $message->getHeader("Content-type"));
|
||||
$message = (new Response())
|
||||
->withAddedHeader('Content-type', 'application/json');
|
||||
$this->assertEquals(['application/json'], $message->getHeader('Content-type'));
|
||||
}
|
||||
|
||||
public function testGetHeaderReturnsMultipleValuesForHeader()
|
||||
{
|
||||
$message = $this->getMockForAbstractClass('\WellRESTed\Message\Message');
|
||||
$message = $message->withAddedHeader("X-name", "cat=Molly");
|
||||
$message = $message->withAddedHeader("X-name", "dog=Bear");
|
||||
$this->assertEquals(["cat=Molly", "dog=Bear"], $message->getHeader("X-name"));
|
||||
$message = (new Response())
|
||||
->withAddedHeader('X-name', 'cat=Molly')
|
||||
->withAddedHeader('X-name', 'dog=Bear');
|
||||
$this->assertEquals(['cat=Molly', 'dog=Bear'], $message->getHeader('X-name'));
|
||||
}
|
||||
|
||||
public function testGetHeaderLineReturnsEmptyStringForUnsetHeader()
|
||||
{
|
||||
$message = $this->getMockForAbstractClass('\WellRESTed\Message\Message');
|
||||
$this->assertSame("", $message->getHeaderLine("X-not-set"));
|
||||
$message = new Response();
|
||||
$this->assertSame('', $message->getHeaderLine('X-not-set'));
|
||||
}
|
||||
|
||||
public function testGetHeaderLineReturnsMultipleHeadersJoinedByCommas()
|
||||
{
|
||||
$message = $this->getMockForAbstractClass('\WellRESTed\Message\Message');
|
||||
$message = $message->withAddedHeader("X-name", "cat=Molly");
|
||||
$message = $message->withAddedHeader("X-name", "dog=Bear");
|
||||
$this->assertEquals("cat=Molly, dog=Bear", $message->getHeaderLine("X-name"));
|
||||
$message = (new Response())
|
||||
->withAddedHeader('X-name', 'cat=Molly')
|
||||
->withAddedHeader('X-name', 'dog=Bear');
|
||||
$this->assertEquals('cat=Molly, dog=Bear', $message->getHeaderLine('X-name'));
|
||||
}
|
||||
|
||||
public function testHasHeaderReturnsTrueWhenHeaderIsSet()
|
||||
{
|
||||
$message = $this->getMockForAbstractClass('\WellRESTed\Message\Message');
|
||||
$message = $message->withHeader("Content-type", "application/json");
|
||||
$this->assertTrue($message->hasHeader("Content-type"));
|
||||
$message = (new Response())
|
||||
->withHeader('Content-type', 'application/json');
|
||||
$this->assertTrue($message->hasHeader('Content-type'));
|
||||
}
|
||||
|
||||
public function testHasHeaderReturnsFalseWhenHeaderIsNotSet()
|
||||
{
|
||||
$message = $this->getMockForAbstractClass('\WellRESTed\Message\Message');
|
||||
$this->assertFalse($message->hasHeader("Content-type"));
|
||||
$message = new Response();
|
||||
$this->assertFalse($message->hasHeader('Content-type'));
|
||||
}
|
||||
|
||||
public function testGetHeadersReturnOriginalHeaderNamesAsKeys()
|
||||
{
|
||||
$message = $this->getMockForAbstractClass('\WellRESTed\Message\Message');
|
||||
$message = $message->withHeader("Set-Cookie", "cat=Molly");
|
||||
$message = $message->withAddedHeader("Set-Cookie", "dog=Bear");
|
||||
$message = $message->withHeader("Content-type", "application/json");
|
||||
$message = (new Response())
|
||||
->withHeader('Set-Cookie', 'cat=Molly')
|
||||
->withAddedHeader('Set-Cookie', 'dog=Bear')
|
||||
->withHeader('Content-type', 'application/json');
|
||||
|
||||
$headers = [];
|
||||
foreach ($message->getHeaders() as $key => $values) {
|
||||
$headers[] = $key;
|
||||
}
|
||||
|
||||
$expected = ["Content-type", "Set-Cookie"];
|
||||
$countUnmatched = count(array_diff($expected, $headers)) + count(array_diff($headers, $expected));
|
||||
$expected = ['Content-type', 'Set-Cookie'];
|
||||
$countUnmatched
|
||||
= count(array_diff($expected, $headers))
|
||||
+ count(array_diff($headers, $expected));
|
||||
$this->assertEquals(0, $countUnmatched);
|
||||
}
|
||||
|
||||
public function testGetHeadersReturnOriginalHeaderNamesAndValues()
|
||||
{
|
||||
$message = $this->getMockForAbstractClass('\WellRESTed\Message\Message');
|
||||
$message = $message->withHeader("Set-Cookie", "cat=Molly");
|
||||
$message = $message->withAddedHeader("Set-Cookie", "dog=Bear");
|
||||
$message = $message->withHeader("Content-type", "application/json");
|
||||
$message = (new Response())
|
||||
->withHeader('Set-Cookie', 'cat=Molly')
|
||||
->withAddedHeader('Set-Cookie', 'dog=Bear')
|
||||
->withHeader('Content-type', 'application/json');
|
||||
|
||||
$headers = [];
|
||||
|
||||
|
|
@ -201,8 +218,8 @@ class MessageTest extends TestCase
|
|||
}
|
||||
|
||||
$expected = [
|
||||
"Set-Cookie" => ["cat=Molly", "dog=Bear"],
|
||||
"Content-type" => ["application/json"]
|
||||
'Set-Cookie' => ['cat=Molly', 'dog=Bear'],
|
||||
'Content-type' => ['application/json']
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, $headers);
|
||||
|
|
@ -213,17 +230,16 @@ class MessageTest extends TestCase
|
|||
|
||||
public function testGetBodyReturnsEmptyStreamByDefault()
|
||||
{
|
||||
$message = $this->getMockForAbstractClass('\WellRESTed\Message\Message');
|
||||
$this->assertEquals("", (string) $message->getBody());
|
||||
$message = new Response();
|
||||
$this->assertEquals('', (string) $message->getBody());
|
||||
}
|
||||
|
||||
public function testGetBodyReturnsAttachedStream()
|
||||
{
|
||||
$stream = $this->prophesize('\Psr\Http\Message\StreamInterface');
|
||||
$stream = $stream->reveal();
|
||||
$stream = new Stream('Hello, world!');
|
||||
|
||||
$message = $this->getMockForAbstractClass('\WellRESTed\Message\Message');
|
||||
$message = $message->withBody($stream);
|
||||
$message = (new Response())
|
||||
->withBody($stream);
|
||||
$this->assertSame($stream, $message->getBody());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace WellRESTed\Test\Unit\Message;
|
||||
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use WellRESTed\Message\UploadedFile;
|
||||
use WellRESTed\Message\UploadedFileState;
|
||||
use WellRESTed\Test\TestCase;
|
||||
|
|
@ -39,7 +40,7 @@ class UploadedFileTest extends TestCase
|
|||
public function testGetStreamReturnsStreamInterface()
|
||||
{
|
||||
$file = new UploadedFile("", "", 0, "", 0);
|
||||
$this->assertInstanceOf('\Psr\Http\Message\StreamInterface', $file->getStream());
|
||||
$this->assertInstanceOf(StreamInterface::class, $file->getStream());
|
||||
}
|
||||
|
||||
public function testGetStreamReturnsStreamWrappingUploadedFile()
|
||||
|
|
|
|||
Loading…
Reference in New Issue