Skip to content

Commit 8336a00

Browse files
committed
Changes MockHttpClient compare body
1 parent 3149c9a commit 8336a00

File tree

1 file changed

+75
-1
lines changed

1 file changed

+75
-1
lines changed

src/Fapi/HttpClient/MockHttpClient.php

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,22 @@
22

33
namespace Fapi\HttpClient;
44

5+
use Exception;
56
use Fapi\HttpClient\Utils\Json;
67
use Psr\Http\Message\RequestInterface;
78
use Psr\Http\Message\ResponseInterface;
9+
use function array_keys;
810
use function array_shift;
911
use function assert;
1012
use function count;
13+
use function implode;
14+
use function ini_set;
15+
use function preg_last_error;
16+
use function preg_match;
17+
use function preg_replace;
18+
use function preg_replace_callback;
19+
use function rtrim;
20+
use function str_replace;
1121
use function strlen;
1222
use function substr;
1323

@@ -20,6 +30,28 @@ class MockHttpClient implements IHttpClient
2030
/** @var array<ResponseInterface> */
2131
private array $responses = [];
2232

33+
/** @var array<string,string> */
34+
public static array $patterns = [
35+
'%%' => '%', // one % character
36+
'%a%' => '[^\r\n]+', // one or more of anything except the end of line characters
37+
'%a\?%' => '[^\r\n]*', // zero or more of anything except the end of line characters
38+
'%A%' => '.+', // one or more of anything including the end of line characters
39+
'%A\?%' => '.*', // zero or more of anything including the end of line characters
40+
'%s%' => '[\t ]+', // one or more white space characters except the end of line characters
41+
'%s\?%' => '[\t ]*', // zero or more white space characters except the end of line characters
42+
'%S%' => '\S+', // one or more of characters except the white space
43+
'%S\?%' => '\S*', // zero or more of characters except the white space
44+
'%c%' => '[^\r\n]', // a single character of any sort (except the end of line)
45+
'%d%' => '[0-9]+', // one or more digits
46+
'%d\?%' => '[0-9]*', // zero or more digits
47+
'%i%' => '[+-]?[0-9]+', // signed integer value
48+
'%f%' => '[+-]?\.?\d+\.?\d*(?:[Ee][+-]?\d+)?', // floating point number
49+
'%h%' => '[0-9a-fA-F]+', // one or more HEX digits
50+
'%w%' => '[0-9a-zA-Z_]+', //one or more alphanumeric characters
51+
'%ds%' => '[\\\\/]', // directory separator
52+
'%(\[.+\][+*?{},\d]*)%' => '$1', // range
53+
];
54+
2355
public function add(RequestInterface $request, ResponseInterface $response): void
2456
{
2557
$this->requests[] = $request;
@@ -94,7 +126,7 @@ private function assertHttpRequestOptions(RequestInterface $expected, RequestInt
94126

95127
private function assertHttpRequestBody(RequestInterface $expected, RequestInterface $actual): void
96128
{
97-
if ((string) $expected->getBody() === (string) $actual->getBody()) {
129+
if (self::isMatching((string) $expected->getBody(), (string) $actual->getBody())) {
98130
return;
99131
}
100132

@@ -116,4 +148,46 @@ private function formatUrl(string $url): string
116148
return $url;
117149
}
118150

151+
public static function isMatching(string $pattern, string $actual, bool $strict = false): bool
152+
{
153+
$old = ini_set('pcre.backtrack_limit', '10000000');
154+
155+
if (!self::isPcre($pattern)) {
156+
$utf8 = (bool) preg_match('#\x80-\x{10FFFF}]#u', $pattern) ? 'u' : '';
157+
$suffix = ($strict ? '$#DsU' : '\s*$#sU') . $utf8;
158+
$patterns = static::$patterns + [
159+
'[.\\\\+*?[^$(){|\#]' => '\$0', // preg quoting
160+
'\x00' => '\x00',
161+
'[\t ]*\r?\n' => '[\t ]*\r?\n', // right trim
162+
];
163+
$pattern = '#^' . preg_replace_callback(
164+
'#' . implode('|', array_keys($patterns)) . '#U' . $utf8,
165+
static function ($m) use ($patterns) {
166+
foreach ($patterns as $re => $replacement) {
167+
$s = preg_replace("#^$re$#D", str_replace('\\', '\\\\', $replacement), $m[0], 1, $count);
168+
if ((bool) $count) {
169+
return $s;
170+
}
171+
}
172+
},
173+
rtrim($pattern, " \t\n\r"),
174+
) . $suffix;
175+
}
176+
177+
$res = preg_match($pattern, $actual);
178+
ini_set('pcre.backtrack_limit', $old);
179+
if ($res === false || (bool) preg_last_error()) {
180+
throw new Exception(
181+
'Error while executing regular expression. (PREG Error Code ' . preg_last_error() . ')',
182+
);
183+
}
184+
185+
return (bool) $res;
186+
}
187+
188+
private static function isPcre(string $pattern): bool
189+
{
190+
return (bool) preg_match('/^([~#]).+(\1)[imsxUu]*$/Ds', $pattern);
191+
}
192+
119193
}

0 commit comments

Comments
 (0)