matchers, symfony serializer support, more tests and fixes

This commit is contained in:
Pavel 2021-05-15 18:57:28 +03:00
parent 25654d921f
commit c85693cbcd
63 changed files with 2629 additions and 142 deletions

View File

@ -37,7 +37,8 @@
"jms/serializer": "^2 | ^3.12",
"symfony/phpunit-bridge": "^5.2",
"symfony/var-dumper": "^5.2",
"symfony/serializer": "^5.2"
"symfony/serializer": "^5.2",
"symfony/property-access": "^5.2"
},
"provide": {
"psr/http-client-implementation": "1.0",

View File

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/squizlabs/php_codesniffer/phpcs.xsd">
<arg name="basepath" value="."/>
<arg name="cache" value=".php_cs.cache"/>
<arg name="colors"/>
<arg name="extensions" value="php"/>
<rule ref="PSR12"/>
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="pock ruleset" xsi:noNamespaceSchemaLocation="vendor/squizlabs/php_codesniffer/phpcs.xsd">
<description>Ruleset for pock</description>
<file>src/</file>
<file>tests/</file>
<arg name="basepath" value="."/>
<arg name="colors"/>
<arg name="cache" pattern=".php_cs.cache"/>
<rule ref="PSR12"/>
</ruleset>

View File

@ -0,0 +1,70 @@
<?php
/**
* PHP 7.1
*
* @category AbstractSymfonySerializerCreator
* @package Pock\Creator
*/
namespace Pock\Creator;
use Pock\Serializer\SerializerInterface;
use Pock\Serializer\SymfonySerializerDecorator;
/**
* Class AbstractSymfonySerializerCreator
*
* @category AbstractSymfonySerializerCreator
* @package Pock\Creator
*/
abstract class AbstractSymfonySerializerCreator implements SerializerCreatorInterface
{
private const OBJECT_NORMALIZER_CLASS = '\Symfony\Component\Serializer\Normalizer\ObjectNormalizer';
private const SERIALIZER_CLASS = '\Symfony\Component\Serializer\Serializer';
/**
* @inheritDoc
*/
public static function create(): ?SerializerInterface
{
if (self::isAvailable()) {
$serializer = self::SERIALIZER_CLASS;
$normalizer = self::OBJECT_NORMALIZER_CLASS;
$encoder = static::getEncoderClass();
return new SymfonySerializerDecorator(
new $serializer([new $normalizer()], [new $encoder()]),
static::getFormat()
);
}
return null;
}
/**
* Returns true if serializer can be instantiated.
*
* @return bool
*/
private static function isAvailable(): bool
{
return class_exists(self::SERIALIZER_CLASS) &&
class_exists(self::OBJECT_NORMALIZER_CLASS) &&
class_exists(static::getEncoderClass());
}
/**
* Returns format for the serializer;
*
* @return string
*/
abstract protected static function getFormat(): string;
/**
* Returns format for the serializer;
*
* @return string
*/
abstract protected static function getEncoderClass(): string;
}

View File

@ -0,0 +1,35 @@
<?php
/**
* PHP 7.1
*
* @category SymfonyJsonSerializerCreator
* @package Pock\Creator
*/
namespace Pock\Creator;
/**
* Class SymfonyJsonSerializerCreator
*
* @category SymfonyJsonSerializerCreator
* @package Pock\Creator
*/
class SymfonyJsonSerializerCreator extends AbstractSymfonySerializerCreator
{
/**
* @inheritDoc
*/
protected static function getFormat(): string
{
return 'json';
}
/**
* @inheritDoc
*/
protected static function getEncoderClass(): string
{
return '\Symfony\Component\Serializer\Encoder\JsonEncoder';
}
}

View File

@ -0,0 +1,35 @@
<?php
/**
* PHP 7.1
*
* @category SymfonyXmlSerializerCreator
* @package Pock\Creator
*/
namespace Pock\Creator;
/**
* Class SymfonyXmlSerializerCreator
*
* @category SymfonyXmlSerializerCreator
* @package Pock\Creator
*/
class SymfonyXmlSerializerCreator extends AbstractSymfonySerializerCreator
{
/**
* @inheritDoc
*/
protected static function getFormat(): string
{
return 'xml';
}
/**
* @inheritDoc
*/
protected static function getEncoderClass(): string
{
return '\Symfony\Component\Serializer\Encoder\XmlEncoder';
}
}

View File

@ -1,7 +1,7 @@
<?php
/**
* PHP 7.3
* PHP 7.1
*
* @category JsonException
* @package Pock\Exception

View File

@ -1,7 +1,7 @@
<?php
/**
* PHP 7.3
* PHP 7.1
*
* @category XmlException
* @package Pock\Exception

View File

@ -10,6 +10,7 @@
namespace Pock\Factory;
use Pock\Creator\JmsJsonSerializerCreator;
use Pock\Creator\SymfonyJsonSerializerCreator;
use Pock\Serializer\SerializerInterface;
/**
@ -30,6 +31,7 @@ class JsonSerializerFactory extends AbstractSerializerFactory
{
return [
JmsJsonSerializerCreator::class,
SymfonyJsonSerializerCreator::class
];
}

View File

@ -10,6 +10,7 @@
namespace Pock\Factory;
use Pock\Creator\JmsXmlSerializerCreator;
use Pock\Creator\SymfonyXmlSerializerCreator;
use Pock\Serializer\SerializerInterface;
/**
@ -29,7 +30,8 @@ class XmlSerializerFactory extends AbstractSerializerFactory
protected static function getCreators(): array
{
return [
JmsXmlSerializerCreator::class
JmsXmlSerializerCreator::class,
SymfonyXmlSerializerCreator::class
];
}

View File

@ -0,0 +1,120 @@
<?php
/**
* PHP 7.1
*
* @category AbstractArrayPoweredComponent
* @package Pock\Matchers
*/
namespace Pock\Matchers;
/**
* Class AbstractArrayPoweredComponent
*
* @category AbstractArrayPoweredComponent
* @package Pock\Matchers
*/
abstract class AbstractArrayPoweredComponent
{
/**
* Returns true if both arrays are equal recursively.
*
* @phpstan-ignore-next-line
* @param array $first
* @phpstan-ignore-next-line
* @param array $second
*
* @return bool
*/
protected static function recursiveCompareArrays(array $first, array $second): bool
{
if (count($first) !== count($second)) {
return false;
}
if (!empty(array_diff(array_keys($first), array_keys($second)))) {
return false;
}
foreach ($first as $key => $value) {
if (is_array($value) && !self::recursiveCompareArrays($value, $second[$key])) {
return false;
}
if ($value !== $second[$key]) {
return false;
}
}
return true;
}
/**
* Returns true if two one-dimensional string arrays are equal.
*
* @phpstan-ignore-next-line
* @param array $first
* @phpstan-ignore-next-line
* @param array $second
*
* @return bool
*/
protected static function compareStringArrays(array $first, array $second): bool
{
return count($first) === count($second) &&
array_diff($first, $second) === array_diff($second, $first);
}
/**
* Returns true if all needle values is present in haystack.
* Doesn't work for multidimensional arrays.
*
* @phpstan-ignore-next-line
* @param array $needle
* @phpstan-ignore-next-line
* @param array $haystack
*
* @return bool
*/
protected static function isNeedlePresentInHaystack(array $needle, array $haystack): bool
{
foreach ($needle as $value) {
if (!in_array($value, $haystack, true)) {
return false;
}
}
return true;
}
/**
* Returns true if all needle values is present in haystack.
* Works for multidimensional arrays. Internal arrays will be treated as values (e.g. will be compared recursively).
*
* @phpstan-ignore-next-line
* @param array $needle
* @phpstan-ignore-next-line
* @param array $haystack
*
* @return bool
*/
protected static function recursiveNeedlePresentInHaystack(array $needle, array $haystack): bool
{
if (!empty(array_diff(array_keys($needle), array_keys($haystack)))) {
return false;
}
foreach ($needle as $key => $value) {
if (is_array($value) && !self::recursiveCompareArrays($value, $haystack[$key])) {
return false;
}
if ($value !== $haystack[$key]) {
return false;
}
}
return true;
}
}

View File

@ -0,0 +1,69 @@
<?php
/**
* PHP 7.1
*
* @category AbstractSerializedBodyMatcher
* @package Pock\Matchers
*/
namespace Pock\Matchers;
use Pock\Traits\SeekableStreamDataExtractor;
use Psr\Http\Message\RequestInterface;
/**
* Class AbstractSerializedBodyMatcher
*
* @category AbstractSerializedBodyMatcher
* @package Pock\Matchers
*/
abstract class AbstractSerializedBodyMatcher extends AbstractArrayPoweredComponent implements RequestMatcherInterface
{
use SeekableStreamDataExtractor;
/** @var array */
private $data; // @phpstan-ignore-line
/**
* AbstractSerializedBodyMatcher constructor.
*
* @phpstan-ignore-next-line
*
* @param array $data
*/
public function __construct(array $data)
{
$this->data = $data;
}
/**
* @inheritDoc
*/
public function matches(RequestInterface $request): bool
{
$body = static::getStreamData($request->getBody());
if ('' === $body) {
return false;
}
$bodyData = $this->deserialize($body);
if (null === $bodyData) {
return false;
}
return self::recursiveCompareArrays($bodyData, $this->data);
}
/**
* Returns an array with deserialized data.
*
* @param string $data
*
* @phpstan-ignore-next-line
* @return array|null
*/
abstract protected function deserialize(string $data): ?array;
}

View File

@ -0,0 +1,73 @@
<?php
/**
* PHP 7.1
*
* @category BodyMatcher
* @package Pock\Matchers
*/
namespace Pock\Matchers;
use Pock\Traits\SeekableStreamDataExtractor;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\StreamInterface;
/**
* Class BodyMatcher
*
* @category BodyMatcher
* @package Pock\Matchers
*/
class BodyMatcher implements RequestMatcherInterface
{
use SeekableStreamDataExtractor;
/** @var string */
protected $contents = '';
/**
* BodyMatcher constructor.
*
* @param \Psr\Http\Message\StreamInterface|resource|string $contents
*/
public function __construct($contents)
{
if (is_string($contents)) {
$this->contents = $contents;
}
if ($contents instanceof StreamInterface) {
$this->contents = static::getStreamData($contents);
}
if (is_resource($contents)) {
$this->contents = static::readAllResource($contents);
}
}
/**
* @inheritDoc
*/
public function matches(RequestInterface $request): bool
{
if (0 === $request->getBody()->getSize()) {
return '' === $this->contents;
}
return static::getStreamData($request->getBody()) === $this->contents;
}
/**
* Reads entire resource data.
*
* @param resource $resource
*
* @return string
*/
protected static function readAllResource($resource): string
{
fseek($resource, 0);
return (string) stream_get_contents($resource);
}
}

View File

@ -0,0 +1,42 @@
<?php
/**
* PHP 7.1
*
* @category CallbackRequestMatcher
* @package Pock\Matchers
*/
namespace Pock\Matchers;
use Psr\Http\Message\RequestInterface;
/**
* Class CallbackRequestMatcher
*
* @category CallbackRequestMatcher
* @package Pock\Matchers
*/
class CallbackRequestMatcher implements RequestMatcherInterface
{
/** @var callable */
private $callback;
/**
* CallbackRequestMatcher constructor.
*
* @param callable $callback
*/
public function __construct(callable $callback)
{
$this->callback = $callback;
}
/**
* @inheritDoc
*/
public function matches(RequestInterface $request): bool
{
return call_user_func($this->callback, $request);
}
}

View File

@ -0,0 +1,33 @@
<?php
/**
* PHP 7.1
*
* @category ExactHeaderMatcher
* @package Pock\Matchers
*/
namespace Pock\Matchers;
use Psr\Http\Message\RequestInterface;
/**
* Class ExactHeaderMatcher
*
* @category ExactHeaderMatcher
* @package Pock\Matchers
*/
class ExactHeaderMatcher extends HeaderMatcher
{
/**
* @inheritDoc
*/
public function matches(RequestInterface $request): bool
{
if (!$request->hasHeader($this->header)) {
return false;
}
return self::compareStringArrays($request->getHeader($this->header), $this->value);
}
}

View File

@ -0,0 +1,81 @@
<?php
/**
* PHP 7.1
*
* @category ExactHeadersMatcher
* @package Pock\Matchers
*/
namespace Pock\Matchers;
use Psr\Http\Message\RequestInterface;
/**
* Class ExactHeadersMatcher
*
* @category ExactHeadersMatcher
* @package Pock\Matchers
*/
class ExactHeadersMatcher extends HeadersMatcher
{
/**
* @inheritDoc
*/
public function matches(RequestInterface $request): bool
{
$requestHeaders = [];
foreach ($request->getHeaders() as $header => $value) {
$requestHeaders[strtolower($header)] = $value;
}
if (isset($requestHeaders['host']) && !$this->expectHeader('host')) {
unset($requestHeaders['host']);
}
if (!static::headerValuesEqual(array_keys($this->headers), array_keys($requestHeaders))) {
return false;
}
foreach ($requestHeaders as $header => $value) {
$expectedValue = is_string($this->headers[$header]) ? [$this->headers[$header]] : $this->headers[$header];
if (!static::headerValuesEqual($value, $expectedValue)) {
return false;
}
}
return true;
}
/**
* Returns true if provided header is expected by the mock.
*
* @param string $name
*
* @return bool
*/
private function expectHeader(string $name): bool
{
foreach (array_keys($this->headers) as $header) {
if (strtolower($header) === strtolower($name)) {
return true;
}
}
return false;
}
/**
* @param string[] $first
* @param string[] $second
*
* @return bool
*/
private static function headerValuesEqual(array $first, array $second): bool
{
return count($first) === count($second) &&
array_diff($first, $second) === array_diff($second, $first);
}
}

View File

@ -0,0 +1,35 @@
<?php
/**
* PHP 7.1
*
* @category ExactQueryMatcher
* @package Pock\Matchers
*/
namespace Pock\Matchers;
use Psr\Http\Message\RequestInterface;
/**
* Class ExactQueryMatcher
*
* @category ExactQueryMatcher
* @package Pock\Matchers
*/
class ExactQueryMatcher extends QueryMatcher
{
/**
* @inheritDoc
*/
public function matches(RequestInterface $request): bool
{
$query = static::parseQuery($request->getUri()->getQuery());
if (empty($query)) {
return false;
}
return self::recursiveCompareArrays($this->query, $query);
}
}

View File

@ -0,0 +1,51 @@
<?php
/**
* PHP 7.1
*
* @category HeaderLineMatcher
* @package Pock\Matchers
*/
namespace Pock\Matchers;
use Psr\Http\Message\RequestInterface;
/**
* Class HeaderLineMatcher
*
* @category HeaderLineMatcher
* @package Pock\Matchers
*/
class HeaderLineMatcher implements RequestMatcherInterface
{
/** @var string */
private $header;
/** @var string */
private $value;
/**
* HeaderLineMatcher constructor.
*
* @param string $header
* @param string $value
*/
public function __construct(string $header, string $value)
{
$this->header = $header;
$this->value = $value;
}
/**
* @inheritDoc
*/
public function matches(RequestInterface $request): bool
{
if (!$request->hasHeader($this->header)) {
return false;
}
return $request->getHeaderLine($this->header) === $this->value;
}
}

View File

@ -0,0 +1,51 @@
<?php
/**
* PHP 7.1
*
* @category HeaderLineRegexpMatcher
* @package Pock\Matchers
*/
namespace Pock\Matchers;
use Psr\Http\Message\RequestInterface;
/**
* Class HeaderLineRegexpMatcher
*
* @category HeaderLineRegexpMatcher
* @package Pock\Matchers
*/
class HeaderLineRegexpMatcher implements RequestMatcherInterface
{
/** @var string */
private $header;
/** @var string */
private $pattern;
/**
* HeaderLineRegexpMatcher constructor.
*
* @param string $header
* @param string $pattern
*/
public function __construct(string $header, string $pattern)
{
$this->header = $header;
$this->pattern = $pattern;
}
/**
* @inheritDoc
*/
public function matches(RequestInterface $request): bool
{
if (!$request->hasHeader($this->header)) {
return false;
}
return 1 === preg_match($this->pattern, $request->getHeaderLine($this->header));
}
}

View File

@ -0,0 +1,56 @@
<?php
/**
* PHP 7.1
*
* @category HeaderMatcher
* @package Pock\Matchers
*/
namespace Pock\Matchers;
use Psr\Http\Message\RequestInterface;
/**
* Class HeaderMatcher
*
* @category HeaderMatcher
* @package Pock\Matchers
*/
class HeaderMatcher extends AbstractArrayPoweredComponent implements RequestMatcherInterface
{
/** @var string */
protected $header;
/** @var string[] */
protected $value;
/**
* HeaderMatcher constructor.
*
* @param string $header
* @param string|string[] $value
*/
public function __construct(string $header, $value)
{
$this->header = $header;
if (is_string($value)) {
$this->value = [$value];
} elseif (is_array($value)) {
$this->value = $value;
}
}
/**
* @inheritDoc
*/
public function matches(RequestInterface $request): bool
{
if (!$request->hasHeader($this->header)) {
return false;
}
return self::isNeedlePresentInHaystack($this->value, $request->getHeader($this->header));
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* PHP 7.1
*
* @category HeadersMatcher
* @package Pock\Matchers
*/
namespace Pock\Matchers;
use Psr\Http\Message\RequestInterface;
/**
* Class HeadersMatcher
*
* @category HeadersMatcher
* @package Pock\Matchers
*/
class HeadersMatcher extends AbstractArrayPoweredComponent implements RequestMatcherInterface
{
/** @var array<string, string|string[]> */
protected $headers;
/**
* HeadersMatcher constructor.
*
* @param array<string, string|string[]> $headers
*/
public function __construct(array $headers)
{
$this->headers = $headers;
}
/**
* @inheritDoc
*/
public function matches(RequestInterface $request): bool
{
foreach (array_keys($this->headers) as $header) {
if (!$request->hasHeader($header)) {
return false;
}
}
foreach ($this->headers as $name => $value) {
if (is_string($value)) {
$value = [$value];
}
if (!static::isNeedlePresentInHaystack($value, $request->getHeader($name))) {
return false;
}
}
return true;
}
}

View File

@ -0,0 +1,37 @@
<?php
/**
* PHP 7.1
*
* @category JsonBodyMatcher
* @package Pock\Matchers
*/
namespace Pock\Matchers;
use Pock\Exception\JsonException;
use Pock\Traits\JsonDecoderTrait;
/**
* Class JsonBodyMatcher
*
* @category JsonBodyMatcher
* @package Pock\Matchers
*/
class JsonBodyMatcher extends AbstractSerializedBodyMatcher
{
use JsonDecoderTrait;
/**
* @phpstan-ignore-next-line
* @inheritDoc
*/
protected function deserialize(string $data): ?array
{
try {
return self::jsonDecode($data, true);
} catch (JsonException $exception) {
return null;
}
}
}

View File

@ -1,7 +1,7 @@
<?php
/**
* PHP 7.3
* PHP 7.1
*
* @category MethodMatcher
* @package Pock\Matchers

View File

@ -0,0 +1,47 @@
<?php
/**
* PHP 7.1
*
* @category PathMatcher
* @package Pock\Matchers
*/
namespace Pock\Matchers;
use Psr\Http\Message\RequestInterface;
/**
* Class PathMatcher
*
* @category PathMatcher
* @package Pock\Matchers
*/
class PathMatcher implements RequestMatcherInterface
{
/** @var string */
private $path;
/**
* PathMatcher constructor.
*
* @param string $path
*/
public function __construct(string $path)
{
if (('' !== $path) && '/' === $path[0]) {
$path = substr($path, 1);
}
$this->path = $path;
}
/**
* @inheritDoc
*/
public function matches(RequestInterface $request): bool
{
return $request->getUri()->getPath() === $this->path ||
$request->getUri()->getPath() === '/' . $this->path;
}
}

View File

@ -0,0 +1,67 @@
<?php
/**
* PHP 7.1
*
* @category QueryMatcher
* @package Pock\Matchers
*/
namespace Pock\Matchers;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\UriInterface;
/**
* Class QueryMatcher
*
* @category QueryMatcher
* @package Pock\Matchers
*/
class QueryMatcher extends AbstractArrayPoweredComponent implements RequestMatcherInterface
{
/** @var array<string, mixed> */
protected $query;
/**
* QueryMatcher constructor.
*
* @param array<string, mixed> $query
*/
public function __construct(array $query)
{
$this->query = $query;
}
/**
* @inheritDoc
*/
public function matches(RequestInterface $request): bool
{
$query = static::parseQuery($request->getUri()->getQuery());
if (empty($query)) {
return false;
}
return self::isNeedlePresentInHaystack($this->query, $query);
}
/**
* Parses query, returns result.
*
* @param string $queryString
*
* @return array<string, mixed>
*/
protected static function parseQuery(string $queryString): array
{
$query = [];
if ('' !== $queryString) {
parse_str($queryString, $query);
}
return $query;
}
}

View File

@ -87,6 +87,14 @@ class Mock implements MockInterface
*/
public function getResponse(): ?ResponseInterface
{
if (
null !== $this->response &&
null !== $this->response->getBody() &&
$this->response->getBody()->isSeekable()
) {
$this->response->getBody()->seek(0);
}
return $this->response;
}

View File

@ -9,25 +9,47 @@
namespace Pock;
use Diff\ArrayComparer\StrictArrayComparer;
use Pock\Enum\RequestMethod;
use Pock\Enum\RequestScheme;
use Pock\Matchers\AnyRequestMatcher;
use Pock\Matchers\BodyMatcher;
use Pock\Matchers\CallbackRequestMatcher;
use Pock\Matchers\ExactHeaderMatcher;
use Pock\Matchers\ExactHeadersMatcher;
use Pock\Matchers\ExactQueryMatcher;
use Pock\Matchers\HeaderLineMatcher;
use Pock\Matchers\HeaderLineRegexpMatcher;
use Pock\Matchers\HeaderMatcher;
use Pock\Matchers\HeadersMatcher;
use Pock\Matchers\HostMatcher;
use Pock\Matchers\JsonBodyMatcher;
use Pock\Matchers\MethodMatcher;
use Pock\Matchers\MultipleMatcher;
use Pock\Matchers\PathMatcher;
use Pock\Matchers\QueryMatcher;
use Pock\Matchers\RequestMatcherInterface;
use Pock\Matchers\SchemeMatcher;
use Pock\Matchers\UriMatcher;
use Pock\Traits\JsonDecoderTrait;
use Pock\Traits\JsonSerializerAwareTrait;
use Psr\Http\Client\ClientInterface;
use Throwable;
/**
* Class PockBuilder
*
* @category PockBuilder
* @package Pock
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @SuppressWarnings(PHPMD.TooManyPublicMethods)
*/
class PockBuilder
{
use JsonDecoderTrait;
use JsonSerializerAwareTrait;
/** @var \Pock\Matchers\MultipleMatcher */
private $matcher;
@ -59,7 +81,7 @@ class PockBuilder
*
* @param string $method
*
* @return $this
* @return self
*/
public function matchMethod(string $method): self
{
@ -102,6 +124,167 @@ class PockBuilder
return $this->addMatcher(new UriMatcher($uri));
}
/**
* Matches request by header value or several values. Header can have other values which are not specified here.
* @see PockBuilder::matchExactHeader() if you want to match exact header values.
*
* @param string $header
* @param string|string[] $value
*
* @return self
*/
public function matchHeader(string $header, $value): self
{
return $this->addMatcher(new HeaderMatcher($header, $value));
}
/**
* Matches request by headers values or several values. Headers can have other values which are not specified here.
* @see PockBuilder::matchExactHeaders() if you want to match exact headers collection.
*
* @param array<string, string|string[]> $headers
*
* @return self
*/
public function matchHeaders(array $headers): self
{
return $this->addMatcher(new HeadersMatcher($headers));
}
/**
* Matches request by the exact header pattern or values.
*
* @param string $header
* @param string|string[] $value
*
* @return self
*/
public function matchExactHeader(string $header, $value): self
{
return $this->addMatcher(new ExactHeaderMatcher($header, $value));
}
/**
* Matches request by headers values or several values.
* Note: only host header will be dropped. Any other headers will not be excluded and can result in the problems
* with the exact matching.
*
* @param array<string, string|string[]> $headers
*
* @return self
*/
public function matchExactHeaders(array $headers): self
{
return $this->addMatcher(new ExactHeadersMatcher($headers));
}
/**
* Matches request by the unparsed header line.
*
* @param string $header
* @param string $value
*
* @return self
*/
public function matchHeaderLine(string $header, string $value): self
{
return $this->addMatcher(new HeaderLineMatcher($header, $value));
}
/**
* Matches request by the unparsed header line using provided regular expression.
*
* @param string $header
* @param string $pattern
*
* @return self
*/
public function matchHeaderLineRegexp(string $header, string $pattern): self
{
return $this->addMatcher(new HeaderLineRegexpMatcher($header, $pattern));
}
/**
* Match request by its path. Path with and without slash at the start will be treated as the same path.
* It's not the same for the path with slash at the end of it.
*
* @param string $path
*
* @return self
*/
public function matchPath(string $path): self
{
return $this->addMatcher(new PathMatcher($path));
}
/**
* Match request by its query. Request can contain other query variables.
* @see PockBuilder::matchExactQuery() if you want to match an entire query string.
*
* @param array<string, mixed> $query
*
* @return self
*/
public function matchQuery(array $query): self
{
return $this->addMatcher(new QueryMatcher($query));
}
/**
* Match request by its query. Additional query parameters aren't allowed.
*
* @param array<string, mixed> $query
*
* @return self
*/
public function matchExactQuery(array $query): self
{
return $this->addMatcher(new ExactQueryMatcher($query));
}
/**
* Match entire request body.
*
* @param \Psr\Http\Message\StreamInterface|resource|string $data
*
* @return self
*/
public function matchBody($data): self
{
return $this->addMatcher(new BodyMatcher($data));
}
/**
* Match JSON request body.
*
* @param mixed $data
*
* @return self
* @throws \Pock\Exception\JsonException
*/
public function matchJsonBody($data): self
{
return $this->addMatcher(new JsonBodyMatcher(
self::jsonDecode(
self::serializeJson($data) ?? '',
true
)
));
}
/**
* Match request using provided callback. Callback should receive RequestInterface and return boolean.
* If returned value is true then request is matched.
*
* @param callable $callback
*
* @return self
*/
public function matchCallback(callable $callback): self
{
return $this->addMatcher(new CallbackRequestMatcher($callback));
}
/**
* Add custom matcher to the mock.
*
@ -123,7 +306,7 @@ class PockBuilder
*
* @param int $hits
*
* @return $this
* @return self
*/
public function repeat(int $hits): self
{
@ -134,6 +317,20 @@ class PockBuilder
return $this;
}
/**
* Throw an exception when request is being sent.
*
* @param \Throwable $throwable
*
* @return self
*/
public function throwException(Throwable $throwable): self
{
$this->throwable = $throwable;
return $this;
}
/**
* @param int $statusCode
*

View File

@ -1,7 +1,7 @@
<?php
/**
* PHP 7.3
* PHP 7.1
*
* @category PockResponseBuilder
* @package Pock
@ -12,11 +12,8 @@ namespace Pock;
use InvalidArgumentException;
use JsonSerializable;
use Nyholm\Psr7\Factory\Psr17Factory;
use Pock\Exception\JsonException;
use Pock\Exception\XmlException;
use Pock\Factory\JsonSerializerFactory;
use Pock\Factory\XmlSerializerFactory;
use Pock\Serializer\SerializerInterface;
use Pock\Traits\JsonSerializerAwareTrait;
use Pock\Traits\XmlSerializerAwareTrait;
use Psr\Http\Message\ResponseInterface;
use RuntimeException;
@ -28,18 +25,15 @@ use RuntimeException;
*/
class PockResponseBuilder
{
use JsonSerializerAwareTrait;
use XmlSerializerAwareTrait;
/** @var \Psr\Http\Message\ResponseInterface */
protected $response;
/** @var Psr17Factory */
protected $factory;
/** @var SerializerInterface|null */
protected static $jsonSerializer;
/** @var SerializerInterface|null */
protected static $xmlSerializer;
/**
* PockResponseBuilder constructor.
*
@ -66,7 +60,7 @@ class PockResponseBuilder
}
/**
* Respond with specified header value.
* Respond with specified header pattern.
* @see \Psr\Http\Message\MessageInterface::withHeader()
*
* @param string $name
@ -82,7 +76,7 @@ class PockResponseBuilder
}
/**
* Respond with specified header value appended to existing header.
* Respond with specified header pattern appended to existing header.
* @see \Psr\Http\Message\MessageInterface::withAddedHeader()
*
* @param string $name
@ -132,8 +126,8 @@ class PockResponseBuilder
/**
* Reply with specified body. It can be:
* - PSR-7 StreamInterface - it will be used without any changes.
* - string - it will be used as stream contents.
* - resource - it's data will be used as stream contents.
* - string - it will be used as contents contents.
* - resource - it's data will be used as contents contents.
*
* @param \Psr\Http\Message\StreamInterface|resource|string $stream
*
@ -189,20 +183,10 @@ class PockResponseBuilder
*/
public function withJson($data): self
{
if (is_string($data) || is_numeric($data)) {
return $this->withBody((string) $data);
}
$result = static::serializeJson($data);
if (is_array($data)) {
return $this->withBody(static::jsonEncode($data));
}
if (is_object($data)) {
if ($data instanceof JsonSerializable) {
return $this->withBody(static::jsonEncode($data));
}
return $this->withBody(static::jsonSerializer()->serialize($data));
if (null !== $result) {
return $this->withBody($result);
}
throw new InvalidArgumentException('Cannot serialize data with type ' . gettype($data));
@ -216,12 +200,10 @@ class PockResponseBuilder
*/
public function withXml($data): self
{
if (is_string($data)) {
return $this->withBody($data);
}
$result = static::serializeXml($data);
if (is_array($data) || is_object($data)) {
return $this->withBody(static::xmlSerializer()->serialize($data));
if (null !== $result) {
return $this->withBody($result);
}
throw new InvalidArgumentException('Cannot serialize data with type ' . gettype($data));
@ -234,69 +216,4 @@ class PockResponseBuilder
{
return $this->response;
}
/**
* Encode JSON, throw an exception on error.
*
* @param mixed $data
*
* @return string
* @throws \Pock\Exception\JsonException
*/
protected static function jsonEncode($data): string
{
$data = json_encode($data);
if (JSON_ERROR_NONE !== json_last_error()) {
throw new JsonException(json_last_error_msg(), json_last_error());
}
return (string) $data;
}
/**
* @return \Pock\Serializer\SerializerInterface
* @throws \Pock\Exception\JsonException
*
* @SuppressWarnings(PHPMD.StaticAccess)
*/
protected static function jsonSerializer(): SerializerInterface
{
if (null !== static::$jsonSerializer) {
return static::$jsonSerializer;
}
$serializer = JsonSerializerFactory::create();
if (null === $serializer) {
throw new JsonException('No JSON serializer available');
}
static::$jsonSerializer = $serializer;
return $serializer;
}
/**
* @return \Pock\Serializer\SerializerInterface
*
* @SuppressWarnings(PHPMD.StaticAccess)
* @throws \Pock\Exception\XmlException
*/
protected static function xmlSerializer(): SerializerInterface
{
if (null !== static::$xmlSerializer) {
return static::$xmlSerializer;
}
$serializer = XmlSerializerFactory::create();
if (null === $serializer) {
throw new XmlException('No XML serializer available');
}
static::$xmlSerializer = $serializer;
return $serializer;
}
}

View File

@ -1,7 +1,7 @@
<?php
/**
* PHP 7.3
* PHP 7.1
*
* @category CallbackSerializerDecorator
* @package Pock\Serializer

View File

@ -0,0 +1,20 @@
<?php
/**
* PHP 7.1
*
* @category SymfonySerializerDecorator
* @package Pock\Serializer
*/
namespace Pock\Serializer;
/**
* Class SymfonySerializerDecorator
*
* @category SymfonySerializerDecorator
* @package Pock\Serializer
*/
class SymfonySerializerDecorator extends JmsSerializerDecorator
{
}

View File

@ -0,0 +1,50 @@
<?php
/**
* PHP 7.1
*
* @category JsonDecoderTrait
* @package Pock\Traits
*/
namespace Pock\Traits;
use Pock\Exception\JsonException;
/**
* Trait JsonDecoderTrait
*
* @category JsonDecoderTrait
* @package Pock\Traits
*/
trait JsonDecoderTrait
{
/**
* json_decode which throws exception on error.
*
* @param string $json
* @param bool|null $associative
* @param int $depth
*
* @param int $flags
*
* @return mixed
* @throws \Pock\Exception\JsonException
*
* @SuppressWarnings(PHPMD.BooleanArgumentFlag)
*/
public static function jsonDecode(
string $json,
?bool $associative = false,
int $depth = 512,
int $flags = 0
) {
$result = json_decode($json, $associative, $depth, $flags);
if (JSON_ERROR_NONE !== json_last_error()) {
throw new JsonException(json_last_error_msg(), json_last_error());
}
return $result;
}
}

View File

@ -0,0 +1,42 @@
<?php
/**
* PHP 7.1
*
* @category JsonEncoderTrait
* @package Pock\Traits
*/
namespace Pock\Traits;
use Pock\Exception\JsonException;
/**
* Trait JsonEncoderTrait
*
* @category JsonEncoderTrait
* @package Pock\Traits
*/
trait JsonEncoderTrait
{
/**
* json_encode which throws exception on error.
*
* @param mixed $data
* @param int $flags
* @param int $depth
*
* @return string
* @throws \Pock\Exception\JsonException
*/
public static function jsonEncode($data, int $flags = 0, int $depth = 512): string
{
$result = json_encode($data, $flags, $depth);
if (JSON_ERROR_NONE !== json_last_error()) {
throw new JsonException(json_last_error_msg(), json_last_error());
}
return (string) $result;
}
}

View File

@ -0,0 +1,82 @@
<?php
/**
* PHP 7.1
*
* @category JsonSerializerAwareTrait
* @package Pock\Traits
*/
namespace Pock\Traits;
use JsonSerializable;
use Pock\Exception\JsonException;
use Pock\Factory\JsonSerializerFactory;
use Pock\Serializer\SerializerInterface;
/**
* Trait JsonSerializerAwareTrait
*
* @category JsonSerializerAwareTrait
* @package Pock\Traits
*/
trait JsonSerializerAwareTrait
{
use JsonEncoderTrait;
/** @var SerializerInterface|null */
protected static $jsonSerializer;
/**
* Returns JSON string if serialization was successful. Returns null otherwise.
* String input value will be treated as JSON and will not be processed in any way.
*
* @param mixed $data
*
* @return string|null
* @throws \Pock\Exception\JsonException
*/
protected static function serializeJson($data): ?string
{
if (is_string($data) || is_numeric($data)) {
return (string) $data;
}
if (is_array($data)) {
return static::jsonEncode($data);
}
if (is_object($data)) {
if ($data instanceof JsonSerializable) {
return static::jsonEncode($data);
}
return static::jsonSerializer()->serialize($data);
}
return null;
}
/**
* @return \Pock\Serializer\SerializerInterface
* @throws \Pock\Exception\JsonException
*
* @SuppressWarnings(PHPMD.StaticAccess)
*/
protected static function jsonSerializer(): SerializerInterface
{
if (null !== static::$jsonSerializer) {
return static::$jsonSerializer;
}
$serializer = JsonSerializerFactory::create();
if (null === $serializer) {
throw new JsonException('No JSON serializer available');
}
static::$jsonSerializer = $serializer;
return $serializer;
}
}

View File

@ -0,0 +1,33 @@
<?php
/**
* PHP 7.1
*
* @category SeekableStreamDataExtractor
* @package Pock\Traits
*/
namespace Pock\Traits;
use Psr\Http\Message\StreamInterface;
/**
* Trait SeekableStreamDataExtractor
*
* @category SeekableStreamDataExtractor
* @package Pock\Traits
*/
trait SeekableStreamDataExtractor
{
/**
* Returns contents contents without honoring a contents pointer.
*
* @param \Psr\Http\Message\StreamInterface $stream
*
* @return string
*/
protected static function getStreamData(StreamInterface $stream): string
{
return $stream->isSeekable() ? $stream->__toString() : $stream->getContents();
}
}

View File

@ -0,0 +1,71 @@
<?php
/**
* PHP 7.1
*
* @category XmlSerializerAwareTrait
* @package Pock\Traits
*/
namespace Pock\Traits;
use Pock\Exception\XmlException;
use Pock\Factory\XmlSerializerFactory;
use Pock\Serializer\SerializerInterface;
/**
* Trait XmlSerializerAwareTrait
*
* @category XmlSerializerAwareTrait
* @package Pock\Traits
*/
trait XmlSerializerAwareTrait
{
/** @var SerializerInterface|null */
protected static $xmlSerializer;
/**
* Returns XML string if serialization was successful. Returns null otherwise.
* String input value will be treated as XML and will not be processed in any way.
*
* @param mixed $data
*
* @return string|null
* @throws \Pock\Exception\XmlException
*/
protected static function serializeXml($data): ?string
{
if (is_string($data)) {
return $data;
}
if (is_array($data) || is_object($data)) {
return static::xmlSerializer()->serialize($data);
}
return null;
}
/**
* @return \Pock\Serializer\SerializerInterface
*
* @SuppressWarnings(PHPMD.StaticAccess)
* @throws \Pock\Exception\XmlException
*/
protected static function xmlSerializer(): SerializerInterface
{
if (null !== static::$xmlSerializer) {
return static::$xmlSerializer;
}
$serializer = XmlSerializerFactory::create();
if (null === $serializer) {
throw new XmlException('No XML serializer available');
}
static::$xmlSerializer = $serializer;
return $serializer;
}
}

View File

@ -27,6 +27,6 @@ class JmsXmlSerializerCreatorTest extends TestCase
$serializer = JmsXmlSerializerCreator::create();
self::assertInstanceOf(SerializerInterface::class, $serializer);
self::assertEquals(SimpleObject::XML, $serializer->serialize(new SimpleObject()));
self::assertEquals(SimpleObject::JMS_XML, $serializer->serialize(new SimpleObject()));
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* PHP 7.1
*
* @category SymfonyJsonSerializerCreatorTest
* @package Pock\Tests\Creator
*/
namespace Pock\Tests\Creator;
use PHPUnit\Framework\TestCase;
use Pock\Creator\SymfonyJsonSerializerCreator;
use Pock\Serializer\SerializerInterface;
use Pock\TestUtils\SimpleObject;
/**
* Class SymfonyJsonSerializerCreatorTest
*
* @category SymfonyJsonSerializerCreatorTest
* @package Pock\Tests\Creator
*/
class SymfonyJsonSerializerCreatorTest extends TestCase
{
public function testCreate(): void
{
$serializer = SymfonyJsonSerializerCreator::create();
self::assertInstanceOf(SerializerInterface::class, $serializer);
self::assertEquals(SimpleObject::JSON, $serializer->serialize(new SimpleObject()));
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* PHP 7.1
*
* @category SymfonyXmlSerializerCreatorTest
* @package Pock\Tests\Creator
*/
namespace Pock\Tests\Creator;
use PHPUnit\Framework\TestCase;
use Pock\Creator\SymfonyXmlSerializerCreator;
use Pock\Serializer\SerializerInterface;
use Pock\TestUtils\SimpleObject;
/**
* Class SymfonyXmlSerializerCreatorTest
*
* @category SymfonyXmlSerializerCreatorTest
* @package Pock\Tests\Creator
*/
class SymfonyXmlSerializerCreatorTest extends TestCase
{
public function testCreate(): void
{
$serializer = SymfonyXmlSerializerCreator::create();
self::assertInstanceOf(SerializerInterface::class, $serializer);
self::assertEquals(SimpleObject::SYMFONY_XML, $serializer->serialize(new SimpleObject()));
}
}

View File

@ -1,7 +1,7 @@
<?php
/**
* PHP 7.3
* PHP 7.1
*
* @category CallbackSerializerDecoratorTest
* @package Pock\Tests\Decorator

View File

@ -1,7 +1,7 @@
<?php
/**
* PHP 7.3
* PHP 7.1
*
* @category AbstractSerializerFactoryTest
* @package Pock\Tests\Factory

View File

@ -27,6 +27,6 @@ class XmlSerializerFactoryTest extends TestCase
$serializer = XmlSerializerFactory::create();
self::assertInstanceOf(SerializerInterface::class, $serializer);
self::assertEquals(SimpleObject::XML, $serializer->serialize(new SimpleObject()));
self::assertEquals(SimpleObject::JMS_XML, $serializer->serialize(new SimpleObject()));
}
}

View File

@ -0,0 +1,61 @@
<?php
/**
* PHP 7.1
*
* @category BodyMatcherTest
* @package Pock\Tests\Matchers
*/
namespace Pock\Tests\Matchers;
use Pock\Enum\RequestMethod;
use Pock\Matchers\BodyMatcher;
use Pock\TestUtils\PockTestCase;
/**
* Class BodyMatcherTest
*
* @category BodyMatcherTest
* @package Pock\Tests\Matchers
*/
class BodyMatcherTest extends PockTestCase
{
public function testNoMatches(): void
{
$request = self::getTestRequest(RequestMethod::POST)
->withBody(self::getPsr17Factory()->createStream('test1'));
$matcher = new BodyMatcher('test');
self::assertFalse($matcher->matches($request));
}
public function testMatchesString(): void
{
$request = self::getTestRequest(RequestMethod::POST)
->withBody(self::getPsr17Factory()->createStream('test'));
$matcher = new BodyMatcher('test');
self::assertTrue($matcher->matches($request));
}
public function testMatchesStream(): void
{
$request = self::getTestRequest(RequestMethod::POST)
->withBody(self::getPsr17Factory()->createStream('test'));
$matcher = new BodyMatcher(self::getPsr17Factory()->createStream('test'));
self::assertTrue($matcher->matches($request));
}
public function testMatchesResource(): void
{
$resource = fopen(__FILE__, 'rb');
$request = self::getTestRequest(RequestMethod::POST)->withBody(self::getPsr17Factory()->createStream(
stream_get_contents($resource)
));
$matcher = new BodyMatcher($resource);
self::assertTrue($matcher->matches($request));
}
}

View File

@ -0,0 +1,40 @@
<?php
/**
* PHP 7.1
*
* @category CallbackRequestMatcherTest
* @package Pock\Tests\Matchers
*/
namespace Pock\Tests\Matchers;
use Pock\Matchers\CallbackRequestMatcher;
use Pock\TestUtils\PockTestCase;
use Psr\Http\Message\RequestInterface;
/**
* Class CallbackRequestMatcherTest
*
* @category CallbackRequestMatcherTest
* @package Pock\Tests\Matchers
*/
class CallbackRequestMatcherTest extends PockTestCase
{
public function testMatches(): void
{
$matcher = new CallbackRequestMatcher(function (RequestInterface $request) {
return '' !== $request->getUri()->getQuery();
});
self::assertFalse($matcher->matches(self::getTestRequest()));
self::assertTrue($matcher->matches(
self::getTestRequest()
->withUri(
self::getTestRequest()
->getUri()
->withQuery('param=value')
)
));
}
}

View File

@ -0,0 +1,60 @@
<?php
/**
* PHP 7.1
*
* @category ExactHeaderMatcherTest
* @package Pock\Tests\Matchers
*/
namespace Pock\Tests\Matchers;
use Pock\Matchers\ExactHeaderMatcher;
use Pock\TestUtils\PockTestCase;
/**
* Class ExactHeaderMatcherTest
*
* @category ExactHeaderMatcherTest
* @package Pock\Tests\Matchers
*/
class ExactHeaderMatcherTest extends PockTestCase
{
public function testNoMatch(): void
{
$matcher = new ExactHeaderMatcher('x-test-header', 'test value');
self::assertFalse($matcher->matches(self::getTestRequest()));
}
public function testMatchStringValue(): void
{
$request = self::getTestRequest()->withHeader('x-test-header', 'test value');
$matcher = new ExactHeaderMatcher('x-test-header', 'test value');
self::assertTrue($matcher->matches($request));
}
public function testMatchArrayValue(): void
{
$request = self::getTestRequest()->withHeader('x-test-header', 'test value');
$matcher = new ExactHeaderMatcher('x-test-header', ['test value']);
self::assertTrue($matcher->matches($request));
}
public function testNotMatchArrayValues(): void
{
$request = self::getTestRequest()->withHeader('x-test-header', ['test value1', 'test value2']);
$matcher = new ExactHeaderMatcher('x-test-header', ['test value1']);
self::assertFalse($matcher->matches($request));
}
public function testMatchArrayValues(): void
{
$request = self::getTestRequest()->withHeader('x-test-header', ['test value1', 'test value2']);
$matcher = new ExactHeaderMatcher('x-test-header', ['test value2', 'test value1']);
self::assertTrue($matcher->matches($request));
}
}

View File

@ -0,0 +1,63 @@
<?php
/**
* PHP 7.1
*
* @category ExactHeadersMatcherTest
* @package Pock\Tests\Matchers
*/
namespace Pock\Tests\Matchers;
use Pock\Matchers\ExactHeadersMatcher;
use Pock\TestUtils\PockTestCase;
/**
* Class ExactHeadersMatcherTest
*
* @category ExactHeadersMatcherTest
* @package Pock\Tests\Matchers
*/
class ExactHeadersMatcherTest extends PockTestCase
{
public function testNoMatch(): void
{
$matcher = new ExactHeadersMatcher(['x-test-header' => 'test value']);
self::assertFalse($matcher->matches(self::getTestRequest()));
}
public function testMatchStringValue(): void
{
$request = self::getTestRequest()->withHeader('x-test-header', 'test value');
$matcher = new ExactHeadersMatcher(['x-test-header' => 'test value']);
self::assertTrue($matcher->matches($request));
}
public function testMatchArrayValue(): void
{
$request = self::getTestRequest()->withHeader('x-test-header', 'test value');
$matcher = new ExactHeadersMatcher(['x-test-header' => ['test value']]);
self::assertTrue($matcher->matches($request));
}
public function testNotMatchArrayValues(): void
{
$request = self::getTestRequest()->withHeader('x-test-header', ['test value1', 'test value2']);
$matcher = new ExactHeadersMatcher(['x-test-header' => ['test value1']]);
self::assertFalse($matcher->matches($request));
}
public function testNoMatchArrayValues(): void
{
$request = self::getTestRequest()->withHeader(
'x-test-header',
['test value1', 'test value2', 'test value 3']
);
$matcher = new ExactHeadersMatcher(['x-test-header' => ['test value2', 'test value1']]);
self::assertFalse($matcher->matches($request));
}
}

View File

@ -0,0 +1,89 @@
<?php
/**
* PHP 7.1
*
* @category ExactQueryMatcherTest
* @package Pock\Tests\Matchers
*/
namespace Pock\Tests\Matchers;
use Pock\Matchers\ExactQueryMatcher;
use Pock\TestUtils\PockTestCase;
/**
* Class ExactQueryMatcherTest
*
* @category ExactQueryMatcherTest
* @package Pock\Tests\Matchers
*/
class ExactQueryMatcherTest extends PockTestCase
{
public function testNoMatches(): void
{
$request = self::getTestRequest()->withUri(self::getTestRequest()->getUri());
$matcher = new ExactQueryMatcher(['var' => 'ok']);
self::assertFalse($matcher->matches($request));
}
/**
* @dataProvider matchesProvider
*/
public function testMatches(array $expected, string $actual, bool $result): void
{
$request = self::getTestRequest()->withUri(
self::getTestRequest()
->getUri()
->withQuery($actual)
);
$matcher = new ExactQueryMatcher($expected);
self::assertEquals($result, $matcher->matches($request));
}
public function matchesProvider(): array
{
return [
[
['var' => 'ok'],
'var=ok',
true
],
[
['var' => 'ok'],
'var=ok&var1=true',
false
],
[
[
'var' => 'ok',
'var1' => 'true',
],
'var=ok&var1=true',
true
],
[
[
'var' => 'ok',
'var1' => 'true',
],
'var=ok',
false
],
[
[
'var' => 'ok',
'x' => [
0 => 'alpha',
1 => 'beta',
'gamma' => ['lambda']
],
],
'var=ok&x[]=alpha&x[]=beta&x[gamma][]=lambda',
true
],
];
}
}

View File

@ -0,0 +1,38 @@
<?php
/**
* PHP 7.1
*
* @category HeaderLineMatcherTest
* @package Pock\Tests\Matchers
*/
namespace Pock\Tests\Matchers;
use Pock\Matchers\HeaderLineMatcher;
use Pock\TestUtils\PockTestCase;
/**
* Class HeaderLineMatcherTest
*
* @category HeaderLineMatcherTest
* @package Pock\Tests\Matchers
*/
class HeaderLineMatcherTest extends PockTestCase
{
public function testNoMatches(): void
{
$request = self::getTestRequest()->withHeader('x-test-header', ['first', 'second']);
$matcher = new HeaderLineMatcher('x-test-header', 'second, first');
self::assertFalse($matcher->matches($request));
}
public function testMatches(): void
{
$request = self::getTestRequest()->withHeader('x-test-header', ['first', 'second']);
$matcher = new HeaderLineMatcher('x-test-header', 'first, second');
self::assertTrue($matcher->matches($request));
}
}

View File

@ -0,0 +1,38 @@
<?php
/**
* PHP 7.1
*
* @category HeaderLineRegexpMatcherTest
* @package Pock\Tests\Matchers
*/
namespace Pock\Tests\Matchers;
use Pock\Matchers\HeaderLineRegexpMatcher;
use Pock\TestUtils\PockTestCase;
/**
* Class HeaderLineRegexpMatcherTest
*
* @category HeaderLineRegexpMatcherTest
* @package Pock\Tests\Matchers
*/
class HeaderLineRegexpMatcherTest extends PockTestCase
{
public function testNoMatches(): void
{
$request = self::getTestRequest()->withHeader('x-test-header', ['first', 'second']);
$matcher = new HeaderLineRegexpMatcher('x-test-header', '/first$/');
self::assertFalse($matcher->matches($request));
}
public function testMatches(): void
{
$request = self::getTestRequest()->withHeader('x-test-header', ['first', 'second']);
$matcher = new HeaderLineRegexpMatcher('x-test-header', '/^first/');
self::assertTrue($matcher->matches($request));
}
}

View File

@ -0,0 +1,52 @@
<?php
/**
* PHP 7.1
*
* @category HeaderMatcherTest
* @package Pock\Tests\Matchers
*/
namespace Pock\Tests\Matchers;
use Pock\Matchers\HeaderMatcher;
use Pock\TestUtils\PockTestCase;
/**
* Class HeaderMatcherTest
*
* @category HeaderMatcherTest
* @package Pock\Tests\Matchers
*/
class HeaderMatcherTest extends PockTestCase
{
public function testNoMatch(): void
{
$matcher = new HeaderMatcher('x-test-header', 'test value');
self::assertFalse($matcher->matches(self::getTestRequest()));
}
public function testMatchStringValue(): void
{
$request = self::getTestRequest()->withHeader('x-test-header', 'test value');
$matcher = new HeaderMatcher('x-test-header', 'test value');
self::assertTrue($matcher->matches($request));
}
public function testMatchArrayValue(): void
{
$request = self::getTestRequest()->withHeader('x-test-header', 'test value');
$matcher = new HeaderMatcher('x-test-header', ['test value']);
self::assertTrue($matcher->matches($request));
}
public function testMatchArrayValues(): void
{
$request = self::getTestRequest()->withHeader('x-test-header', ['test value1', 'test value2']);
$matcher = new HeaderMatcher('x-test-header', ['test value1']);
self::assertTrue($matcher->matches($request));
}
}

View File

@ -0,0 +1,60 @@
<?php
/**
* PHP 7.1
*
* @category HeadersMatcherTest
* @package Pock\Tests\Matchers
*/
namespace Pock\Tests\Matchers;
use Pock\Matchers\HeadersMatcher;
use Pock\TestUtils\PockTestCase;
/**
* Class HeadersMatcherTest
*
* @category HeadersMatcherTest
* @package Pock\Tests\Matchers
*/
class HeadersMatcherTest extends PockTestCase
{
public function testNoMatch(): void
{
$matcher = new HeadersMatcher(['x-test-header' => 'test value']);
self::assertFalse($matcher->matches(self::getTestRequest()));
}
public function testMatchStringValue(): void
{
$request = self::getTestRequest()->withHeader('x-test-header', 'test value');
$matcher = new HeadersMatcher(['x-test-header' => 'test value']);
self::assertTrue($matcher->matches($request));
}
public function testMatchArrayValue(): void
{
$request = self::getTestRequest()->withHeader('x-test-header', 'test value');
$matcher = new HeadersMatcher(['x-test-header' => ['test value']]);
self::assertTrue($matcher->matches($request));
}
public function testMatchArrayValues(): void
{
$request = self::getTestRequest()->withHeader('x-test-header', ['test value1', 'test value2']);
$matcher = new HeadersMatcher(['x-test-header' => ['test value1']]);
self::assertTrue($matcher->matches($request));
}
public function testNoMatchArrayValues(): void
{
$request = self::getTestRequest()->withHeader('x-test-header', ['test value2']);
$matcher = new HeadersMatcher(['x-test-header' => ['test value1']]);
self::assertFalse($matcher->matches($request));
}
}

View File

@ -20,6 +20,11 @@ use Pock\TestUtils\PockTestCase;
*/
class HostMatcherTest extends PockTestCase
{
public function testNotMatches(): void
{
self::assertFalse((new HostMatcher('test.com'))->matches(static::getTestRequest()));
}
public function testMatches(): void
{
self::assertTrue((new HostMatcher(self::TEST_HOST))->matches(static::getTestRequest()));

View File

@ -0,0 +1,65 @@
<?php
/**
* PHP 7.1
*
* @category JsonBodyMatcherTest
* @package Pock\Tests\Matchers
*/
namespace Pock\Tests\Matchers;
use Pock\Enum\RequestMethod;
use Pock\Matchers\JsonBodyMatcher;
use Pock\TestUtils\PockTestCase;
/**
* Class JsonBodyMatcherTest
*
* @category JsonBodyMatcherTest
* @package Pock\Tests\Matchers
*/
class JsonBodyMatcherTest extends PockTestCase
{
public function testInvalidJson(): void
{
$request = self::getTestRequest(RequestMethod::POST)
->withBody(self::getPsr17Factory()->createStream('test1'));
$matcher = new JsonBodyMatcher(['field' => 'value']);
self::assertFalse($matcher->matches($request));
}
public function testNoMatches(): void
{
$data = [
'field' => [
'items' => [
'another' => 'value'
]
]
];
$request = self::getTestRequest(RequestMethod::POST)
->withBody(self::getPsr17Factory()->createStream(json_encode($data)));
$data['field']['items']['another2'] = 'value2';
$matcher = new JsonBodyMatcher($data);
self::assertFalse($matcher->matches($request));
}
public function testMatches(): void
{
$data = [
'field' => [
'items' => [
'another' => 'value'
]
]
];
$request = self::getTestRequest(RequestMethod::POST)
->withBody(self::getPsr17Factory()->createStream(json_encode($data)));
$matcher = new JsonBodyMatcher($data);
self::assertTrue($matcher->matches($request));
}
}

View File

@ -0,0 +1,51 @@
<?php
/**
* PHP 7.1
*
* @category PathMatcherTest
* @package Pock\Tests\Matchers
*/
namespace Pock\Tests\Matchers;
use Pock\Matchers\PathMatcher;
use Pock\TestUtils\PockTestCase;
/**
* Class PathMatcherTest
*
* @category PathMatcherTest
* @package Pock\Tests\Matchers
*/
class PathMatcherTest extends PockTestCase
{
public function testNoMatches(): void
{
$request = self::getTestRequest()->withUri(self::getTestRequest()->getUri()->withPath('/test/path'));
$matcher = new PathMatcher('/test/path/here');
self::assertFalse($matcher->matches($request));
}
/**
* @dataProvider matchesProvider
*/
public function testMatches(string $expected, string $actual): void
{
$request = self::getTestRequest()->withUri(self::getTestRequest()->getUri()->withPath($actual));
$matcher = new PathMatcher($expected);
self::assertTrue($matcher->matches($request));
}
public function matchesProvider(): array
{
return [
['/test/path', '/test/path'],
['/test/path', 'test/path'],
['test/path', '/test/path'],
['test/path', 'test/path']
];
}
}

View File

@ -0,0 +1,89 @@
<?php
/**
* PHP 7.1
*
* @category QueryMatcherTest
* @package Pock\Tests\Matchers
*/
namespace Pock\Tests\Matchers;
use Pock\Matchers\QueryMatcher;
use Pock\TestUtils\PockTestCase;
/**
* Class QueryMatcherTest
*
* @category QueryMatcherTest
* @package Pock\Tests\Matchers
*/
class QueryMatcherTest extends PockTestCase
{
public function testNoMatches(): void
{
$request = self::getTestRequest()->withUri(self::getTestRequest()->getUri());
$matcher = new QueryMatcher(['var' => 'ok']);
self::assertFalse($matcher->matches($request));
}
/**
* @dataProvider matchesProvider
*/
public function testMatches(array $expected, string $actual, bool $result): void
{
$request = self::getTestRequest()->withUri(
self::getTestRequest()
->getUri()
->withQuery($actual)
);
$matcher = new QueryMatcher($expected);
self::assertEquals($result, $matcher->matches($request));
}
public function matchesProvider(): array
{
return [
[
['var' => 'ok'],
'var=ok',
true
],
[
['var' => 'ok'],
'var=ok&var1=true',
true
],
[
[
'var' => 'ok',
'var1' => 'true',
],
'var=ok&var1=true',
true
],
[
[
'var' => 'ok',
'var1' => 'true',
],
'var=ok',
false
],
[
[
'var' => 'ok',
'x' => [
0 => 'alpha',
1 => 'beta',
'gamma' => ['lambda']
],
],
'var=ok&x[]=alpha&x[]=beta&x[gamma][]=lambda',
true
],
];
}
}

View File

@ -21,6 +21,11 @@ use Pock\TestUtils\PockTestCase;
*/
class SchemeMatcherTest extends PockTestCase
{
public function testNotMatches(): void
{
self::assertFalse((new SchemeMatcher(RequestScheme::HTTP))->matches(static::getTestRequest()));
}
public function testMatches(): void
{
self::assertTrue((new SchemeMatcher(RequestScheme::HTTPS))->matches(static::getTestRequest()));

View File

@ -22,6 +22,7 @@ class UriMatcherTest extends PockTestCase
{
public function testMatches(): void
{
self::assertFalse((new UriMatcher('https://test.com'))->matches(static::getTestRequest()));
self::assertTrue((new UriMatcher(self::TEST_URI))->matches(static::getTestRequest()));
self::assertTrue((new UriMatcher(static::getPsr17Factory()->createUri(self::TEST_URI)))
->matches(static::getTestRequest()));

View File

@ -1,7 +1,7 @@
<?php
/**
* PHP 7.3
* PHP 7.1
*
* @category PockBuilderTest
* @package Pock\Tests
@ -11,9 +11,13 @@ namespace Pock\Tests;
use Pock\Enum\RequestMethod;
use Pock\Enum\RequestScheme;
use Pock\Exception\UniversalMockException;
use Pock\Exception\UnsupportedRequestException;
use Pock\PockBuilder;
use Pock\TestUtils\PockTestCase;
use Psr\Http\Client\ClientExceptionInterface;
use Psr\Http\Message\RequestInterface;
use RuntimeException;
/**
* Class PockBuilderTest
@ -27,7 +31,179 @@ class PockBuilderTest extends PockTestCase
{
$this->expectException(UnsupportedRequestException::class);
(new PockBuilder())->getClient()->sendRequest(self::getPsr17Factory()
->createRequest(RequestMethod::GET, 'https://example.com'));
->createRequest(RequestMethod::GET, self::TEST_URI));
}
public function testThrowException(): void
{
$this->expectException(ClientExceptionInterface::class);
$builder = new PockBuilder();
$builder->matchMethod(RequestMethod::GET)
->matchScheme(RequestScheme::HTTPS)
->matchHost(self::TEST_HOST)
->throwException(new UniversalMockException('Boom!'));
$builder->getClient()->sendRequest(
self::getPsr17Factory()->createRequest(RequestMethod::GET, self::TEST_URI)
);
}
public function testMatchHeader(): void
{
$builder = new PockBuilder();
$builder->matchMethod(RequestMethod::GET)
->matchScheme(RequestScheme::HTTPS)
->matchHost(self::TEST_HOST)
->matchHeader('Authorization', 'Token token')
->reply(200)
->withHeader('Content-Type', 'text/plain')
->withBody('Successful');
$response = $builder->getClient()->sendRequest(
self::getPsr17Factory()
->createRequest(RequestMethod::GET, self::TEST_URI)
->withHeader('Authorization', 'Token token')
);
self::assertEquals(200, $response->getStatusCode());
self::assertEquals(['Content-Type' => ['text/plain']], $response->getHeaders());
self::assertEquals('Successful', $response->getBody()->getContents());
}
public function testMatchHeaders(): void
{
$builder = new PockBuilder();
$builder->matchMethod(RequestMethod::GET)
->matchScheme(RequestScheme::HTTPS)
->matchHost(self::TEST_HOST)
->matchHeaders(['Authorization' => 'Token token'])
->reply(200)
->withHeader('Content-Type', 'text/plain')
->withBody('Successful');
$response = $builder->getClient()->sendRequest(
self::getPsr17Factory()
->createRequest(RequestMethod::GET, self::TEST_URI)
->withHeader('Authorization', 'Token token')
);
self::assertEquals(200, $response->getStatusCode());
self::assertEquals(['Content-Type' => ['text/plain']], $response->getHeaders());
self::assertEquals('Successful', $response->getBody()->getContents());
}
public function testMatchExactHeader(): void
{
$builder = new PockBuilder();
$builder->matchMethod(RequestMethod::GET)
->matchScheme(RequestScheme::HTTPS)
->matchHost(self::TEST_HOST)
->matchExactHeader('Authorization', ['Token token', 'Token second_token'])
->reply(200)
->withHeader('Content-Type', 'text/plain')
->withBody('Successful');
$response = $builder->getClient()->sendRequest(
self::getPsr17Factory()
->createRequest(RequestMethod::GET, self::TEST_URI)
->withHeader('Authorization', ['Token token', 'Token second_token'])
);
self::assertEquals(200, $response->getStatusCode());
self::assertEquals(['Content-Type' => ['text/plain']], $response->getHeaders());
self::assertEquals('Successful', $response->getBody()->getContents());
}
public function testMatchHeaderLine(): void
{
$builder = new PockBuilder();
$builder->matchMethod(RequestMethod::GET)
->matchScheme(RequestScheme::HTTPS)
->matchHost(self::TEST_HOST)
->matchHeaderLine('Authorization', 'Token token, Token second_token')
->reply(200)
->withHeader('Content-Type', 'text/plain')
->withBody('Successful');
$response = $builder->getClient()->sendRequest(
self::getPsr17Factory()
->createRequest(RequestMethod::GET, self::TEST_URI)
->withHeader('Authorization', ['Token token', 'Token second_token'])
);
self::assertEquals(200, $response->getStatusCode());
self::assertEquals(['Content-Type' => ['text/plain']], $response->getHeaders());
self::assertEquals('Successful', $response->getBody()->getContents());
}
public function testMatchHeaderLineRegexp(): void
{
$builder = new PockBuilder();
$builder->matchMethod(RequestMethod::GET)
->matchScheme(RequestScheme::HTTPS)
->matchHost(self::TEST_HOST)
->matchHeaderLineRegexp('Authorization', '/^Token [a-z_]+$/')
->reply(200)
->withHeader('Content-Type', 'text/plain')
->withBody('Successful');
$response = $builder->getClient()->sendRequest(
self::getPsr17Factory()
->createRequest(RequestMethod::GET, self::TEST_URI)
->withHeader('Authorization', 'Token token')
);
self::assertEquals(200, $response->getStatusCode());
self::assertEquals(['Content-Type' => ['text/plain']], $response->getHeaders());
self::assertEquals('Successful', $response->getBody()->getContents());
}
public function testMatchPathResponse(): void
{
$builder = new PockBuilder();
$builder->matchMethod(RequestMethod::GET)
->matchScheme(RequestScheme::HTTPS)
->matchHost(self::TEST_HOST)
->matchPath('/test')
->reply(403)
->withHeader('Content-Type', 'text/plain')
->withBody('Forbidden');
$response = $builder->getClient()->sendRequest(
self::getPsr17Factory()
->createRequest(RequestMethod::GET, self::TEST_URI)
->withUri(self::getPsr17Factory()->createUri(self::TEST_URI . 'test'))
);
self::assertEquals(403, $response->getStatusCode());
self::assertEquals(['Content-Type' => ['text/plain']], $response->getHeaders());
self::assertEquals('Forbidden', $response->getBody()->getContents());
}
public function testMatchCallback(): void
{
$builder = new PockBuilder();
$builder->matchMethod(RequestMethod::GET)
->matchScheme(RequestScheme::HTTPS)
->matchHost(self::TEST_HOST)
->matchPath('/test')
->matchCallback(static function (RequestInterface $request) {
return '' === $request->getUri()->getQuery();
})
->reply(403)
->withHeader('Content-Type', 'text/plain')
->withBody('Forbidden');
$response = $builder->getClient()->sendRequest(
self::getPsr17Factory()
->createRequest(RequestMethod::GET, self::TEST_URI)
->withUri(self::getPsr17Factory()->createUri(self::TEST_URI . 'test'))
);
self::assertEquals(403, $response->getStatusCode());
self::assertEquals(['Content-Type' => ['text/plain']], $response->getHeaders());
self::assertEquals('Forbidden', $response->getBody()->getContents());
}
public function testTextResponse(): void
@ -35,13 +211,14 @@ class PockBuilderTest extends PockTestCase
$builder = new PockBuilder();
$builder->matchMethod(RequestMethod::GET)
->matchScheme(RequestScheme::HTTPS)
->matchHost('example.com')
->matchHost(self::TEST_HOST)
->reply(403)
->withHeader('Content-Type', 'text/plain')
->withBody('Forbidden');
$response = $builder->getClient()->sendRequest(self::getPsr17Factory()
->createRequest(RequestMethod::GET, 'https://example.com'));
$response = $builder->getClient()->sendRequest(
self::getPsr17Factory()->createRequest(RequestMethod::GET, self::TEST_URI)
);
self::assertEquals(403, $response->getStatusCode());
self::assertEquals(['Content-Type' => ['text/plain']], $response->getHeaders());
@ -53,13 +230,14 @@ class PockBuilderTest extends PockTestCase
$builder = new PockBuilder();
$builder->matchMethod(RequestMethod::GET)
->matchScheme(RequestScheme::HTTPS)
->matchHost('example.com')
->matchHost(self::TEST_HOST)
->reply(403)
->withHeader('Content-Type', 'application/json')
->withJson(['error' => 'Forbidden']);
$response = $builder->getClient()->sendRequest(self::getPsr17Factory()
->createRequest(RequestMethod::GET, 'https://example.com'));
$response = $builder->getClient()->sendRequest(
self::getPsr17Factory()->createRequest(RequestMethod::GET, self::TEST_URI)
);
self::assertEquals(403, $response->getStatusCode());
self::assertEquals(['Content-Type' => ['application/json']], $response->getHeaders());
@ -80,16 +258,151 @@ EOF;
$builder = new PockBuilder();
$builder->matchMethod(RequestMethod::GET)
->matchScheme(RequestScheme::HTTPS)
->matchHost('example.com')
->matchHost(self::TEST_HOST)
->reply(403)
->withHeader('Content-Type', 'text/xml')
->withXml(['error' => 'Forbidden']);
$response = $builder->getClient()->sendRequest(self::getPsr17Factory()
->createRequest(RequestMethod::GET, 'https://example.com'));
$response = $builder->getClient()->sendRequest(
self::getPsr17Factory()->createRequest(RequestMethod::GET, self::TEST_URI)
);
self::assertEquals(403, $response->getStatusCode());
self::assertEquals(['Content-Type' => ['text/xml']], $response->getHeaders());
self::assertEquals($xml, $response->getBody()->getContents());
}
public function testSeveralMocks(): void
{
$builder = new PockBuilder();
$builder->matchMethod(RequestMethod::GET)
->matchScheme(RequestScheme::HTTPS)
->matchHost(self::TEST_HOST)
->matchPath('/ping')
->matchHeader('Authorization', 'Token token_1')
->repeat(2)
->reply(200)
->withHeader('Content-Type', 'text/plain')
->withBody('First token');
$builder->matchMethod(RequestMethod::GET)
->matchScheme(RequestScheme::HTTPS)
->matchHost(self::TEST_HOST)
->matchPath('/ping')
->matchHeader('Authorization', 'Token token_2')
->reply(200)
->withHeader('Content-Type', 'text/plain')
->withBody('Second token');
$builder->matchMethod(RequestMethod::GET)
->matchScheme(RequestScheme::HTTPS)
->matchHost(self::TEST_HOST)
->matchPath('/ping')
->matchExactQuery(['param1' => 'value'])
->matchHeader('Authorization', 'Token token_2')
->reply(200)
->withHeader('Content-Type', 'text/plain')
->withBody('Second token (exact query params)');
$builder->matchMethod(RequestMethod::GET)
->matchScheme(RequestScheme::HTTPS)
->matchHost(self::TEST_HOST)
->matchPath('/ping')
->matchQuery(['param1' => 'value'])
->matchHeader('Authorization', 'Token token_2')
->reply(200)
->withHeader('Content-Type', 'text/plain')
->withBody('Second token (query params)');
$builder->matchMethod(RequestMethod::POST)
->matchScheme(RequestScheme::HTTPS)
->matchHost(self::TEST_HOST)
->matchPath('/ping')
->matchHeaders([
'Authorization' => 'Token token_2',
'Content-Type' => 'application/json'
])
->matchJsonBody(['field' => 'value'])
->reply(200)
->withHeader('Content-Type', 'text/plain')
->withBody('Second token (post json)');
$builder->matchMethod(RequestMethod::POST)
->matchScheme(RequestScheme::HTTPS)
->matchHost(self::TEST_HOST)
->matchPath('/ping')
->matchHeader('Authorization', 'Token token_2')
->matchBody('test data')
->reply(200)
->withHeader('Content-Type', 'text/plain')
->withBody('Second token (post)');
$client = $builder->getClient();
for ($i = 0; $i < 2; $i++) {
$response = $client->sendRequest(
self::getPsr17Factory()
->createRequest(RequestMethod::GET, self::TEST_URI)
->withHeader('Authorization', 'Token token_1')
->withUri(self::getPsr17Factory()->createUri(self::TEST_URI . 'ping'))
);
self::assertEquals(
'First token',
$response->getBody()->getContents(),
'Attempt #' . ($i + 1) . ' for repeatable mock'
);
}
$response = $client->sendRequest(
self::getPsr17Factory()
->createRequest(RequestMethod::GET, self::TEST_URI)
->withHeader('Authorization', 'Token token_2')
->withUri(self::getPsr17Factory()->createUri(self::TEST_URI . 'ping'))
);
self::assertEquals('Second token', $response->getBody()->getContents());
$response = $client->sendRequest(
self::getPsr17Factory()
->createRequest(RequestMethod::GET, self::TEST_URI)
->withHeader('Authorization', 'Token token_2')
->withUri(
self::getPsr17Factory()
->createUri(self::TEST_URI . 'ping')
->withQuery('param1=value')
)
);
self::assertEquals('Second token (exact query params)', $response->getBody()->getContents());
$response = $client->sendRequest(
self::getPsr17Factory()
->createRequest(RequestMethod::GET, self::TEST_URI)
->withHeader('Authorization', 'Token token_2')
->withUri(
self::getPsr17Factory()
->createUri(self::TEST_URI . 'ping')
->withQuery('param1=value&param2=value')
)
);
self::assertEquals('Second token (query params)', $response->getBody()->getContents());
$response = $client->sendRequest(
self::getPsr17Factory()
->createRequest(RequestMethod::POST, self::TEST_URI)
->withHeader('Authorization', 'Token token_2')
->withHeader('Content-Type', 'application/json')
->withUri(self::getPsr17Factory()->createUri(self::TEST_URI . 'ping'))
->withBody(self::getPsr17Factory()->createStream('{"field": "value"}'))
);
self::assertEquals('Second token (post json)', $response->getBody()->getContents());
$response = $client->sendRequest(
self::getPsr17Factory()
->createRequest(RequestMethod::POST, self::TEST_URI)
->withHeader('Authorization', 'Token token_2')
->withUri(self::getPsr17Factory()->createUri(self::TEST_URI . 'ping'))
->withBody(self::getPsr17Factory()->createStream('test data'))
);
self::assertEquals('Second token (post)', $response->getBody()->getContents());
}
}

View File

@ -1,7 +1,7 @@
<?php
/**
* PHP 7.3
* PHP 7.1
*
* @category PockResponseBuilderTest
* @package Pock\Tests
@ -157,7 +157,7 @@ class PockResponseBuilderTest extends PockTestCase
return [
[1, '1'],
['{}', '{}'],
[['key' => 'value'], '{"key":"value"}'],
[['key' => 'pattern'], '{"key":"pattern"}'],
[new SimpleObjectJsonSerializable(), SimpleObjectJsonSerializable::JSON],
[new SimpleObject(), SimpleObject::JSON]
];
@ -176,8 +176,8 @@ class PockResponseBuilderTest extends PockTestCase
EOF;
return [
[SimpleObject::XML, SimpleObject::XML],
[new SimpleObject(), SimpleObject::XML],
[SimpleObject::JMS_XML, SimpleObject::JMS_XML],
[new SimpleObject(), SimpleObject::JMS_XML],
[[new SimpleObject()], $xmlArray]
];
}

View File

@ -1,7 +1,7 @@
<?php
/**
* PHP 7.3
* PHP 7.1
*
* @category EmptyJsonSerializerDecorator
* @package Pock\TestUtils

View File

@ -1,7 +1,7 @@
<?php
/**
* PHP 7.3
* PHP 7.1
*
* @category EmptyXmlSerializerDecorator
* @package Pock\TestUtils

View File

@ -1,7 +1,7 @@
<?php
/**
* PHP 7.3
* PHP 7.1
*
* @category PockBuilderTestCase
* @package Pock\TestUtils

View File

@ -32,11 +32,13 @@ abstract class PockTestCase extends TestCase
protected static $psr17Factory;
/**
* @param string|null $method
*
* @return \Psr\Http\Message\RequestInterface
*/
protected static function getTestRequest(): RequestInterface
protected static function getTestRequest(?string $method = null): RequestInterface
{
return static::getPsr17Factory()->createRequest(static::TEST_METHOD, static::TEST_URI);
return static::getPsr17Factory()->createRequest($method ?? static::TEST_METHOD, static::TEST_URI);
}
/**

View File

@ -20,13 +20,19 @@ use JMS\Serializer\Annotation as JMS;
class SimpleObject
{
public const JSON = '{"field":"test"}';
public const XML = <<<'EOF'
public const JMS_XML = <<<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<result>
<field><![CDATA[test]]></field>
</result>
EOF;
public const SYMFONY_XML = <<<'EOF'
<?xml version="1.0"?>
<response><field>test</field></response>
EOF;
/**
* @var string
@ -34,5 +40,5 @@ EOF;
* @JMS\Type("string")
* @JMS\SerializedName("field")
*/
protected $field = 'test';
public $field = 'test';
}

View File

@ -1,7 +1,7 @@
<?php
/**
* PHP 7.3
* PHP 7.1
*
* @category SimpleObjectJsonSerializable
* @package Pock\TestUtils