Browse Source

vendor

master
chuan 2 months ago
parent
commit
abd59d7522
  1. 15
      app/admin/controller/Notice.php
  2. 4
      app/admin/route/app.php
  3. 25
      app/admin/service/AgentService.php
  4. 34
      app/admin/service/NoticeService.php
  5. 1
      app/admin/service/auth/AuthRuleService.php
  6. 7
      app/home/controller/Country.php
  7. 4
      app/model/AdminModel.php
  8. 16
      composer.json
  9. 55
      composer.lock
  10. BIN
      vendor.zip
  11. 2
      vendor/autoload.php
  12. 5
      vendor/bin/var-dump-server.bat
  13. 10
      vendor/composer/autoload_real.php
  14. 12
      vendor/composer/autoload_static.php
  15. 379
      vendor/composer/installed.json
  16. 28
      vendor/composer/installed.php
  17. 9
      vendor/guzzlehttp/promises/.editorconfig
  18. 13
      vendor/guzzlehttp/promises/.gitattributes
  19. 2
      vendor/guzzlehttp/promises/.github/.editorconfig
  20. 2
      vendor/guzzlehttp/promises/.github/FUNDING.yml
  21. 14
      vendor/guzzlehttp/promises/.github/stale.yml
  22. 21
      vendor/guzzlehttp/promises/.github/workflows/checks.yml
  23. 58
      vendor/guzzlehttp/promises/.github/workflows/ci.yml
  24. 82
      vendor/guzzlehttp/promises/.github/workflows/static.yml
  25. 7
      vendor/guzzlehttp/promises/.gitignore
  26. 28
      vendor/guzzlehttp/promises/.php-cs-fixer.dist.php
  27. 13
      vendor/guzzlehttp/promises/Makefile
  28. 8
      vendor/guzzlehttp/promises/phpstan-baseline.neon
  29. 7
      vendor/guzzlehttp/promises/phpstan.neon.dist
  30. 21
      vendor/guzzlehttp/promises/phpunit.xml.dist
  31. 2
      vendor/guzzlehttp/promises/psalm-baseline.xml
  32. 18
      vendor/guzzlehttp/promises/psalm.xml
  33. 18
      vendor/guzzlehttp/promises/tests/AggregateExceptionTest.php
  34. 115
      vendor/guzzlehttp/promises/tests/CoroutineTest.php
  35. 58
      vendor/guzzlehttp/promises/tests/CreateTest.php
  36. 433
      vendor/guzzlehttp/promises/tests/EachPromiseTest.php
  37. 36
      vendor/guzzlehttp/promises/tests/EachTest.php
  38. 115
      vendor/guzzlehttp/promises/tests/FulfilledPromiseTest.php
  39. 42
      vendor/guzzlehttp/promises/tests/IsTest.php
  40. 51
      vendor/guzzlehttp/promises/tests/NotPromiseInstance.php
  41. 773
      vendor/guzzlehttp/promises/tests/PromiseTest.php
  42. 29
      vendor/guzzlehttp/promises/tests/PropertyHelper.php
  43. 151
      vendor/guzzlehttp/promises/tests/RejectedPromiseTest.php
  44. 30
      vendor/guzzlehttp/promises/tests/RejectionExceptionTest.php
  45. 35
      vendor/guzzlehttp/promises/tests/TaskQueueTest.php
  46. 27
      vendor/guzzlehttp/promises/tests/Thennable.php
  47. 20
      vendor/guzzlehttp/promises/tests/Thing1.php
  48. 14
      vendor/guzzlehttp/promises/tests/Thing2.php
  49. 734
      vendor/guzzlehttp/promises/tests/UtilsTest.php
  50. 9
      vendor/guzzlehttp/promises/vendor-bin/php-cs-fixer/composer.json
  51. 10
      vendor/guzzlehttp/promises/vendor-bin/phpstan/composer.json
  52. 9
      vendor/guzzlehttp/promises/vendor-bin/psalm/composer.json
  53. 12
      vendor/guzzlehttp/psr7/.editorconfig
  54. 13
      vendor/guzzlehttp/psr7/.gitattributes
  55. 2
      vendor/guzzlehttp/psr7/.github/.editorconfig
  56. 2
      vendor/guzzlehttp/psr7/.github/FUNDING.yml
  57. 14
      vendor/guzzlehttp/psr7/.github/stale.yml
  58. 21
      vendor/guzzlehttp/psr7/.github/workflows/checks.yml
  59. 58
      vendor/guzzlehttp/psr7/.github/workflows/ci.yml
  60. 45
      vendor/guzzlehttp/psr7/.github/workflows/integration.yml
  61. 82
      vendor/guzzlehttp/psr7/.github/workflows/static.yml
  62. 7
      vendor/guzzlehttp/psr7/.gitignore
  63. 28
      vendor/guzzlehttp/psr7/.php-cs-fixer.dist.php
  64. 18
      vendor/guzzlehttp/psr7/Makefile
  65. 751
      vendor/guzzlehttp/psr7/phpstan-baseline.neon
  66. 11
      vendor/guzzlehttp/psr7/phpstan.neon.dist
  67. 35
      vendor/guzzlehttp/psr7/phpunit.xml.dist
  68. 137
      vendor/guzzlehttp/psr7/psalm-baseline.xml
  69. 18
      vendor/guzzlehttp/psr7/psalm.xml
  70. 221
      vendor/guzzlehttp/psr7/tests/AppendStreamTest.php
  71. 65
      vendor/guzzlehttp/psr7/tests/BufferStreamTest.php
  72. 200
      vendor/guzzlehttp/psr7/tests/CachingStreamTest.php
  73. 30
      vendor/guzzlehttp/psr7/tests/DroppingStreamTest.php
  74. 128
      vendor/guzzlehttp/psr7/tests/FnStreamTest.php
  75. 13
      vendor/guzzlehttp/psr7/tests/HasToString.php
  76. 182
      vendor/guzzlehttp/psr7/tests/HeaderTest.php
  77. 97
      vendor/guzzlehttp/psr7/tests/InflateStreamTest.php
  78. 44
      vendor/guzzlehttp/psr7/tests/Integration/ServerRequestFromGlobalsTest.php
  79. 15
      vendor/guzzlehttp/psr7/tests/Integration/server.php
  80. 68
      vendor/guzzlehttp/psr7/tests/LazyOpenStreamTest.php
  81. 165
      vendor/guzzlehttp/psr7/tests/LimitStreamTest.php
  82. 299
      vendor/guzzlehttp/psr7/tests/MessageTest.php
  83. 25
      vendor/guzzlehttp/psr7/tests/MimeTypeTest.php
  84. 330
      vendor/guzzlehttp/psr7/tests/MultipartStreamTest.php
  85. 38
      vendor/guzzlehttp/psr7/tests/NoSeekStreamTest.php
  86. 105
      vendor/guzzlehttp/psr7/tests/PumpStreamTest.php
  87. 124
      vendor/guzzlehttp/psr7/tests/QueryTest.php
  88. 26
      vendor/guzzlehttp/psr7/tests/ReadSeekOnlyStream.php
  89. 362
      vendor/guzzlehttp/psr7/tests/RequestTest.php
  90. 391
      vendor/guzzlehttp/psr7/tests/ResponseTest.php
  91. 566
      vendor/guzzlehttp/psr7/tests/ServerRequestTest.php
  92. 148
      vendor/guzzlehttp/psr7/tests/StreamDecoratorTraitTest.php
  93. 447
      vendor/guzzlehttp/psr7/tests/StreamTest.php
  94. 202
      vendor/guzzlehttp/psr7/tests/StreamWrapperTest.php
  95. 210
      vendor/guzzlehttp/psr7/tests/UploadedFileTest.php
  96. 45
      vendor/guzzlehttp/psr7/tests/UriComparatorTest.php
  97. 180
      vendor/guzzlehttp/psr7/tests/UriNormalizerTest.php
  98. 210
      vendor/guzzlehttp/psr7/tests/UriResolverTest.php
  99. 722
      vendor/guzzlehttp/psr7/tests/UriTest.php
  100. 551
      vendor/guzzlehttp/psr7/tests/UtilsTest.php

15
app/admin/controller/Notice.php

@ -0,0 +1,15 @@
<?php
namespace app\admin\controller;
use app\admin\service\NoticeService;
class Notice extends AdminBaseController
{
// 弹窗通知消息
public function popUp()
{
$returnData = (new NoticeService())->popUp($this->request->param());
return json($returnData);
}
}

4
app/admin/route/app.php

@ -14,7 +14,7 @@ $header = [
//Route::get('/test', 'Test/index');
Route::post('/test', 'Test/index');
Route::post('/test_upload', 'Upload/uploadVideo');
Route::post('test_api', 'document.Index/informationArticleList');
Route::post('test_api', 'Notice/popUp');
Route::group('/', function () {
// 上传图片
Route::post('/upload', 'Upload/upload');
@ -30,6 +30,8 @@ Route::group('/', function () {
Route::post('config/sms_template_list', 'Config/smsTemplateList'); //获取短信模板列表
Route::post('config/edit_sms_template', 'Config/editSmsTemplate'); //编辑短信模板
Route::post('notice/popup', 'Notice/popUp'); // 弹窗推送消息
// 渠道列表
Route::post('/channel/list', 'Channel/list'); //渠道列表
Route::post('/channel/add', 'Channel/add')->middleware('admin_log'); //新增渠道

25
app/admin/service/AgentService.php

@ -259,13 +259,30 @@ class AgentService extends AdminBaseService
if (empty($user)) {
return $this->toData('500', '用户数据为空');
}
// 变更的客服必须是同一个代理
// 变更的客服必须是同一个代理 $user->agent_id
$newCustomer = AdminModel::where(['id'=>$param['new_customer_id']])->find();
if (empty($newCustomer)) {
return $this->toData('500', '客服数据错误');
return $this->toData('500', '变更的客服数据错误');
}
if ($newCustomer->parent_id != $user->agent_id) {
return $this->toData('500', '变更的客服不属于同一个代理');
if ($newCustomer->ext == 2) {
return $this->toData('500', '要变更的客服已经停止接待');
}
// 获取新客服所属的代理, 需要先获取所属的组长、总监、代理
$teamHeader = AdminModel::where(['id'=>$newCustomer->parent_id])->find(); // 获取所属组长
if (empty($teamHeader)) {
return $this->toData('500', '新客服所属的组长为空');
}
$director = AdminModel::where(['id'=>$teamHeader->parent_id])->find(); // 获取所属总监
if (empty($director)) {
return $this->toData('500', '新客服所属的总监为空');
}
$agent = AdminModel::where(['id'=>$director->parent_id])->find(); // 获取所属代理
if (empty($agent)) {
return $this->toData('500', '新客服所属的代理为空');
}
// 判断新客服所属的代理是否与旧客服的代理是同一个
if ($agent->id != $user->agent_id) {
return $this->toData('500', '变更的客服与当前客服不属于同一个代理');
}
// 变更客服绑定关系
$user->customer_id = $param['new_customer_id'];

34
app/admin/service/NoticeService.php

@ -0,0 +1,34 @@
<?php
namespace app\admin\service;
use GatewayClient\Gateway;
require_once __DIR__ . '/../../../vendor/autoload.php';
class NoticeService extends AdminBaseService
{
public function popUp($param)
{
try {
if (empty($param['user_id']) || empty($param['content'])) {
return $this->toData('400', '参数错误');
}
if (!is_string($param['content'])) {
return $this->toData('400', 'content参数必须为string类型');
}
// 多个用户ID之间用英文逗号隔开的
$expUserID = explode(',', $param['user_id']);
if (count($expUserID) <= 0) {
return $this->toData('400', '用户ID不能为空');
}
// 循环向每个用户发送弹窗
Gateway::$registerAddress = env('GATEWAY_SERVER.REGISTER');
foreach ($expUserID as $uid) {
Gateway::sendToUid($uid, $param['content']);
}
return $this->toData('0', 'ok');
} catch (\Exception $e) {
return $this->toData('500', 'The system error', [$e->getMessage(), $e->getTrace()]);
}
}
}

1
app/admin/service/auth/AuthRuleService.php

@ -158,6 +158,7 @@ class AuthRuleService extends AdminBaseService
$role=AuthRoleModel::find($user->role_id);
$authRule=AuthRuleModel::whereIn('id',$role->rules)->order('sort', 'asc')->select()->toArray();
}
// $authRule=AuthRuleModel::whereIn('id',$role->rules)->order('sort', 'asc')->select()->toArray();
// $authRule=AuthRuleModel::order('sort', 'asc')->select()->toArray();//显示全部
$menus=[];

7
app/home/controller/Country.php

@ -15,7 +15,12 @@ class Country extends HomeBaseController
public function getAll(): Json
{
try {
$res = CountryModel::getAll();
$param = $this->request->post();
if (!empty($param['name'])) {
$res = CountryModel::where('name_cn', $param['name'])->select();
} else {
$res = CountryModel::getAll();
}
$returnData = [];
if(!$res->isEmpty()){
$deny = explode(',', env('NATION.DENY_NATION'));

4
app/model/AdminModel.php

@ -104,8 +104,8 @@ class AdminModel extends BaseModel
if (empty($teamHeaders)) {
return [];
}
// 获取组长下的客服ID
$customers = self::where('parent_id', 'in', $teamHeaders)->column('id');
// 获取组长下的客服ID 注意:ext = 1 表示启用中的客服,ext = 2表示客服停用了
$customers = self::where('parent_id', 'in', $teamHeaders)->where('ext', 1)->column('id');
if (empty($customers)) {
return [];
}

16
composer.json

@ -21,22 +21,22 @@
],
"require": {
"php": ">=7.2.5",
"topthink/framework": "^6.1.3",
"topthink/think-orm": "^2.0.61",
"topthink/think-filesystem": "^1.0.3",
"topthink/think-multi-app": "^1.0.17",
"phpmailer/phpmailer": "^6.8.0",
"alibabacloud/client": "^1.5.32",
"topthink/framework": "6.1.3",
"topthink/think-orm": "2.0.61",
"topthink/think-filesystem": "1.0.3",
"topthink/think-multi-app": "1.0.17",
"phpmailer/phpmailer": "6.8.0",
"alibabacloud/client": "1.5.32",
"firebase/php-jwt": "^6.8",
"topthink/think-queue": "^3.0",
"itinysun/tp-model-helper": "^1.0",
"geoip2/geoip2": "^2.13",
"geoip2/geoip2": "2.13",
"guzzlehttp/guzzle": "^7.7",
"lcobucci/jwt": "^4.0",
"phpoffice/phpspreadsheet": "^1.29",
"ext-json": "*",
"aws/aws-sdk-php": "^3.337",
"workerman/gatewayclient": "^3.1.0"
"workerman/gatewayclient": "^3.1"
},
"require-dev": {
"symfony/var-dumper": "^4.2",

55
composer.lock

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "15c087650de9711db93c55ece5ab738a",
"content-hash": "58b5bfa65a7e22b95bf7405c3e384c23",
"packages": [
{
"name": "adbario/php-dot-notation",
@ -2286,16 +2286,16 @@
},
{
"name": "phpmailer/phpmailer",
"version": "v6.9.3",
"version": "v6.8.0",
"source": {
"type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "2f5c94fe7493efc213f643c23b1b1c249d40f47e"
"reference": "df16b615e371d81fb79e506277faea67a1be18f1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/2f5c94fe7493efc213f643c23b1b1c249d40f47e",
"reference": "2f5c94fe7493efc213f643c23b1b1c249d40f47e",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/df16b615e371d81fb79e506277faea67a1be18f1",
"reference": "df16b615e371d81fb79e506277faea67a1be18f1",
"shasum": "",
"mirrors": [
{
@ -2311,17 +2311,16 @@
"php": ">=5.5.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^1.0",
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.2",
"doctrine/annotations": "^1.2.6 || ^1.13.3",
"php-parallel-lint/php-console-highlighter": "^1.0.0",
"php-parallel-lint/php-parallel-lint": "^1.3.2",
"phpcompatibility/php-compatibility": "^9.3.5",
"roave/security-advisories": "dev-latest",
"squizlabs/php_codesniffer": "^3.7.2",
"squizlabs/php_codesniffer": "^3.7.1",
"yoast/phpunit-polyfills": "^1.0.4"
},
"suggest": {
"decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication",
"ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses",
"ext-openssl": "Needed for secure SMTP sending and DKIM signing",
"greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication",
@ -2361,7 +2360,7 @@
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"support": {
"issues": "https://github.com/PHPMailer/PHPMailer/issues",
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.9.3"
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.8.0"
},
"funding": [
{
@ -2369,7 +2368,7 @@
"type": "github"
}
],
"time": "2024-11-24T18:04:13+00:00"
"time": "2023-03-06T14:43:22+00:00"
},
{
"name": "phpoffice/phpspreadsheet",
@ -3689,16 +3688,16 @@
},
{
"name": "topthink/framework",
"version": "v6.1.5",
"version": "v6.1.3",
"source": {
"type": "git",
"url": "https://github.com/top-think/framework.git",
"reference": "57d1950a1844ef8d3098ea290032aeb92e2e32c3"
"reference": "7c324e7011246f0064b055b62ab9c3921cf0a041"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/framework/zipball/57d1950a1844ef8d3098ea290032aeb92e2e32c3",
"reference": "57d1950a1844ef8d3098ea290032aeb92e2e32c3",
"url": "https://api.github.com/repos/top-think/framework/zipball/7c324e7011246f0064b055b62ab9c3921cf0a041",
"reference": "7c324e7011246f0064b055b62ab9c3921cf0a041",
"shasum": "",
"mirrors": [
{
@ -3754,9 +3753,9 @@
],
"support": {
"issues": "https://github.com/top-think/framework/issues",
"source": "https://github.com/top-think/framework/tree/v6.1.5"
"source": "https://github.com/top-think/framework/tree/v6.1.3"
},
"time": "2024-04-16T02:01:19+00:00"
"time": "2023-05-22T03:02:08+00:00"
},
{
"name": "topthink/think-filesystem",
@ -3866,16 +3865,16 @@
},
{
"name": "topthink/think-multi-app",
"version": "v1.1.1",
"version": "v1.0.17",
"source": {
"type": "git",
"url": "https://github.com/top-think/think-multi-app.git",
"reference": "f93c604d5cfac2b613756273224ee2f88e457b88"
"reference": "4055a6187296ac16c0bc7bbab4ed5d92f82f791c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/think-multi-app/zipball/f93c604d5cfac2b613756273224ee2f88e457b88",
"reference": "f93c604d5cfac2b613756273224ee2f88e457b88",
"url": "https://api.github.com/repos/top-think/think-multi-app/zipball/4055a6187296ac16c0bc7bbab4ed5d92f82f791c",
"reference": "4055a6187296ac16c0bc7bbab4ed5d92f82f791c",
"shasum": "",
"mirrors": [
{
@ -3914,22 +3913,22 @@
"description": "thinkphp multi app support",
"support": {
"issues": "https://github.com/top-think/think-multi-app/issues",
"source": "https://github.com/top-think/think-multi-app/tree/v1.1.1"
"source": "https://github.com/top-think/think-multi-app/tree/v1.0.17"
},
"time": "2024-11-25T08:52:44+00:00"
"time": "2023-03-29T02:04:29+00:00"
},
{
"name": "topthink/think-orm",
"version": "v2.0.62",
"version": "v2.0.61",
"source": {
"type": "git",
"url": "https://github.com/top-think/think-orm.git",
"reference": "e53bfea572a133039ad687077120de5521af617f"
"reference": "10528ebf4a5106b19c3bac9c6deae7a67ff49de6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/think-orm/zipball/e53bfea572a133039ad687077120de5521af617f",
"reference": "e53bfea572a133039ad687077120de5521af617f",
"url": "https://api.github.com/repos/top-think/think-orm/zipball/10528ebf4a5106b19c3bac9c6deae7a67ff49de6",
"reference": "10528ebf4a5106b19c3bac9c6deae7a67ff49de6",
"shasum": "",
"mirrors": [
{
@ -3975,9 +3974,9 @@
],
"support": {
"issues": "https://github.com/top-think/think-orm/issues",
"source": "https://github.com/top-think/think-orm/tree/v2.0.62"
"source": "https://github.com/top-think/think-orm/tree/v2.0.61"
},
"time": "2024-09-22T06:17:47+00:00"
"time": "2023-04-20T14:27:51+00:00"
},
{
"name": "topthink/think-queue",

BIN
vendor.zip

Binary file not shown.

2
vendor/autoload.php

@ -19,4 +19,4 @@ if (PHP_VERSION_ID < 50600) {
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit15c087650de9711db93c55ece5ab738a::getLoader();
return ComposerAutoloaderInitdd94061c596fec45ed08426e6d417237::getLoader();

5
vendor/bin/var-dump-server.bat

@ -1,5 +0,0 @@
@ECHO OFF
setlocal DISABLEDELAYEDEXPANSION
SET BIN_TARGET=%~dp0/var-dump-server
SET COMPOSER_RUNTIME_BIN_DIR=%~dp0
php "%BIN_TARGET%" %*

10
vendor/composer/autoload_real.php

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit15c087650de9711db93c55ece5ab738a
class ComposerAutoloaderInitdd94061c596fec45ed08426e6d417237
{
private static $loader;
@ -24,16 +24,16 @@ class ComposerAutoloaderInit15c087650de9711db93c55ece5ab738a
require __DIR__ . '/platform_check.php';
spl_autoload_register(array('ComposerAutoloaderInit15c087650de9711db93c55ece5ab738a', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInitdd94061c596fec45ed08426e6d417237', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit15c087650de9711db93c55ece5ab738a', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInitdd94061c596fec45ed08426e6d417237', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit15c087650de9711db93c55ece5ab738a::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInitdd94061c596fec45ed08426e6d417237::getInitializer($loader));
$loader->register(true);
$filesToLoad = \Composer\Autoload\ComposerStaticInit15c087650de9711db93c55ece5ab738a::$files;
$filesToLoad = \Composer\Autoload\ComposerStaticInitdd94061c596fec45ed08426e6d417237::$files;
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;

12
vendor/composer/autoload_static.php

@ -4,7 +4,7 @@
namespace Composer\Autoload;
class ComposerStaticInit15c087650de9711db93c55ece5ab738a
class ComposerStaticInitdd94061c596fec45ed08426e6d417237
{
public static $files = array (
'9b552a3cc426e3287cc811caefa3cf53' => __DIR__ . '/..' . '/topthink/think-helper/src/helper.php',
@ -407,11 +407,11 @@ class ComposerStaticInit15c087650de9711db93c55ece5ab738a
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit15c087650de9711db93c55ece5ab738a::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit15c087650de9711db93c55ece5ab738a::$prefixDirsPsr4;
$loader->prefixesPsr0 = ComposerStaticInit15c087650de9711db93c55ece5ab738a::$prefixesPsr0;
$loader->fallbackDirsPsr0 = ComposerStaticInit15c087650de9711db93c55ece5ab738a::$fallbackDirsPsr0;
$loader->classMap = ComposerStaticInit15c087650de9711db93c55ece5ab738a::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInitdd94061c596fec45ed08426e6d417237::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitdd94061c596fec45ed08426e6d417237::$prefixDirsPsr4;
$loader->prefixesPsr0 = ComposerStaticInitdd94061c596fec45ed08426e6d417237::$prefixesPsr0;
$loader->fallbackDirsPsr0 = ComposerStaticInitdd94061c596fec45ed08426e6d417237::$fallbackDirsPsr0;
$loader->classMap = ComposerStaticInitdd94061c596fec45ed08426e6d417237::$classMap;
}, null, ClassLoader::class);
}

379
vendor/composer/installed.json

@ -13,13 +13,7 @@
"type": "zip",
"url": "https://api.github.com/repos/adbario/php-dot-notation/zipball/081e2cca50c84bfeeea2e3ef9b2c8d206d80ccae",
"reference": "081e2cca50c84bfeeea2e3ef9b2c8d206d80ccae",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"ext-json": "*",
@ -75,13 +69,7 @@
"type": "zip",
"url": "https://api.github.com/repos/aliyun/openapi-sdk-php-client/zipball/5bc6f6d660797dcee2c3aef29700ab41ee764f4d",
"reference": "5bc6f6d660797dcee2c3aef29700ab41ee764f4d",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"adbario/php-dot-notation": "^2.4.1",
@ -416,13 +404,7 @@
"type": "zip",
"url": "https://api.github.com/repos/clagiordano/weblibs-configmanager/zipball/5c8ebcc62782313b1278afe802b120d18c07a059",
"reference": "5c8ebcc62782313b1278afe802b120d18c07a059",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"php": ">=5.4"
@ -792,13 +774,7 @@
"type": "zip",
"url": "https://api.github.com/repos/maxmind/GeoIP2-php/zipball/6a41d8fbd6b90052bc34dff3b4252d0f88067b23",
"reference": "6a41d8fbd6b90052bc34dff3b4252d0f88067b23",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"ext-json": "*",
@ -859,13 +835,7 @@
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/d281ed313b989f213357e3be1a179f02196ac99b",
"reference": "d281ed313b989f213357e3be1a179f02196ac99b",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"ext-json": "*",
@ -1017,7 +987,7 @@
"forward-command": false
}
},
"installation-source": "source",
"installation-source": "dist",
"autoload": {
"psr-4": {
"GuzzleHttp\\Promise\\": "src/"
@ -1120,7 +1090,7 @@
"forward-command": false
}
},
"installation-source": "source",
"installation-source": "dist",
"autoload": {
"psr-4": {
"GuzzleHttp\\Psr7\\": "src/"
@ -1211,13 +1181,7 @@
"type": "zip",
"url": "https://api.github.com/repos/Itinysun/tp-model-helper/zipball/ab280d3ad6321ef4c3951690153520d34497323f",
"reference": "ab280d3ad6321ef4c3951690153520d34497323f",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"phpdocumentor/reflection-docblock": "^3.1",
@ -1232,12 +1196,12 @@
"type": "library",
"extra": {
"think": {
"config": {
"model_help": "config/config.php"
},
"services": [
"itinysun\\model\\helper\\Service"
]
],
"config": {
"model_help": "config/config.php"
}
}
},
"installation-source": "dist",
@ -1434,13 +1398,7 @@
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/3239285c825c152bcc315fe0e87d6b55f5972ed1",
"reference": "3239285c825c152bcc315fe0e87d6b55f5972ed1",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"ext-fileinfo": "*",
@ -1476,7 +1434,7 @@
"dev-master": "1.1-dev"
}
},
"installation-source": "dist",
"installation-source": "source",
"autoload": {
"psr-4": {
"League\\Flysystem\\": "src/"
@ -1537,13 +1495,7 @@
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem-cached-adapter/zipball/d1925efb2207ac4be3ad0c40b8277175f99ffaff",
"reference": "d1925efb2207ac4be3ad0c40b8277175f99ffaff",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"league/flysystem": "~1.0",
@ -1561,7 +1513,7 @@
},
"time": "2020-07-25T15:56:04+00:00",
"type": "library",
"installation-source": "dist",
"installation-source": "source",
"autoload": {
"psr-4": {
"League\\Flysystem\\Cached\\": "src/"
@ -1597,13 +1549,7 @@
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301",
"reference": "ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"ext-fileinfo": "*",
@ -1616,7 +1562,7 @@
},
"time": "2024-01-28T23:22:08+00:00",
"type": "library",
"installation-source": "dist",
"installation-source": "source",
"autoload": {
"psr-4": {
"League\\MimeTypeDetection\\": "src"
@ -1749,13 +1695,7 @@
"type": "zip",
"url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
"reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0"
@ -1809,13 +1749,7 @@
"type": "zip",
"url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/728434227fe21be27ff6d86621a1b13107a2562c",
"reference": "728434227fe21be27ff6d86621a1b13107a2562c",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
@ -2134,7 +2068,7 @@
"dev-master": "3.x-dev"
}
},
"installation-source": "source",
"installation-source": "dist",
"autoload": {
"psr-4": {
"Carbon\\": "src/Carbon/"
@ -2196,13 +2130,7 @@
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
"reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"php": ">=5.5"
@ -2370,24 +2298,18 @@
},
{
"name": "phpmailer/phpmailer",
"version": "v6.9.3",
"version_normalized": "6.9.3.0",
"version": "v6.8.0",
"version_normalized": "6.8.0.0",
"source": {
"type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "2f5c94fe7493efc213f643c23b1b1c249d40f47e"
"reference": "df16b615e371d81fb79e506277faea67a1be18f1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/2f5c94fe7493efc213f643c23b1b1c249d40f47e",
"reference": "2f5c94fe7493efc213f643c23b1b1c249d40f47e",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/df16b615e371d81fb79e506277faea67a1be18f1",
"reference": "df16b615e371d81fb79e506277faea67a1be18f1",
"shasum": ""
},
"require": {
"ext-ctype": "*",
@ -2396,17 +2318,16 @@
"php": ">=5.5.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^1.0",
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.2",
"doctrine/annotations": "^1.2.6 || ^1.13.3",
"php-parallel-lint/php-console-highlighter": "^1.0.0",
"php-parallel-lint/php-parallel-lint": "^1.3.2",
"phpcompatibility/php-compatibility": "^9.3.5",
"roave/security-advisories": "dev-latest",
"squizlabs/php_codesniffer": "^3.7.2",
"squizlabs/php_codesniffer": "^3.7.1",
"yoast/phpunit-polyfills": "^1.0.4"
},
"suggest": {
"decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication",
"ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses",
"ext-openssl": "Needed for secure SMTP sending and DKIM signing",
"greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication",
@ -2416,7 +2337,7 @@
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)",
"thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication"
},
"time": "2024-11-24T18:04:13+00:00",
"time": "2023-03-06T14:43:22+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@ -2448,7 +2369,7 @@
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"support": {
"issues": "https://github.com/PHPMailer/PHPMailer/issues",
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.9.3"
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.8.0"
},
"funding": [
{
@ -2586,13 +2507,7 @@
"type": "zip",
"url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8",
"reference": "d11b50ad223250cf17b86e38383413f5a6764bf8",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"php": ">=5.3.0"
@ -2604,7 +2519,7 @@
"dev-master": "1.0.x-dev"
}
},
"installation-source": "dist",
"installation-source": "source",
"autoload": {
"psr-4": {
"Psr\\Cache\\": "src/"
@ -2644,13 +2559,7 @@
"type": "zip",
"url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d",
"reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"php": "^7.0 || ^8.0"
@ -2701,20 +2610,14 @@
"type": "zip",
"url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea",
"reference": "513e0666f7216c7459170d56df27dfcefe1689ea",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"php": ">=7.4.0"
},
"time": "2021-11-05T16:50:12+00:00",
"type": "library",
"installation-source": "dist",
"installation-source": "source",
"autoload": {
"psr-4": {
"Psr\\Container\\": "src/"
@ -2758,13 +2661,7 @@
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90",
"reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"php": "^7.0 || ^8.0",
@ -2883,13 +2780,7 @@
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba",
"reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0"
@ -2901,7 +2792,7 @@
"dev-master": "1.1.x-dev"
}
},
"installation-source": "dist",
"installation-source": "source",
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
@ -2945,13 +2836,7 @@
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11",
"reference": "d49695b909c3b7628b6289db5479a1c204601f11",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"php": ">=5.3.0"
@ -2963,7 +2848,7 @@
"dev-master": "1.1.x-dev"
}
},
"installation-source": "dist",
"installation-source": "source",
"autoload": {
"psr-4": {
"Psr\\Log\\": "Psr/Log/"
@ -3004,13 +2889,7 @@
"type": "zip",
"url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
"reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"php": ">=5.3.0"
@ -3022,7 +2901,7 @@
"dev-master": "1.0.x-dev"
}
},
"installation-source": "dist",
"installation-source": "source",
"autoload": {
"psr-4": {
"Psr\\SimpleCache\\": "src/"
@ -3064,13 +2943,7 @@
"type": "zip",
"url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
"reference": "120b605dfeb996808c31b6477290a714d356e822",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"php": ">=5.6"
@ -3173,13 +3046,7 @@
"type": "zip",
"url": "https://api.github.com/repos/symfony/class-loader/zipball/a22265a9f3511c0212bf79f54910ca5a77c0e92c",
"reference": "a22265a9f3511c0212bf79f54910ca5a77c0e92c",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"php": "^5.5.9|>=7.0.8"
@ -3410,13 +3277,7 @@
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341",
"reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"php": ">=7.2"
@ -3435,7 +3296,7 @@
"url": "https://github.com/symfony/polyfill"
}
},
"installation-source": "dist",
"installation-source": "source",
"autoload": {
"files": [
"bootstrap.php"
@ -3499,13 +3360,7 @@
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/fa2ae56c44f03bed91a39bfc9822e31e7c5c38ce",
"reference": "fa2ae56c44f03bed91a39bfc9822e31e7c5c38ce",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"php": ">=7.2"
@ -3572,13 +3427,7 @@
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8",
"reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"php": ">=7.2"
@ -3587,11 +3436,11 @@
"type": "library",
"extra": {
"thanks": {
"url": "https://github.com/symfony/polyfill",
"name": "symfony/polyfill"
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"installation-source": "dist",
"installation-source": "source",
"autoload": {
"files": [
"bootstrap.php"
@ -4006,13 +3855,7 @@
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/1069c7a3fca74578022fab6f81643248d02f8e63",
"reference": "1069c7a3fca74578022fab6f81643248d02f8e63",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"php": ">=7.1.3",
@ -4040,7 +3883,7 @@
"Resources/bin/var-dump-server"
],
"type": "library",
"installation-source": "dist",
"installation-source": "source",
"autoload": {
"files": [
"Resources/functions/dump.php"
@ -4093,24 +3936,18 @@
},
{
"name": "topthink/framework",
"version": "v6.1.5",
"version_normalized": "6.1.5.0",
"version": "v6.1.3",
"version_normalized": "6.1.3.0",
"source": {
"type": "git",
"url": "https://github.com/top-think/framework.git",
"reference": "57d1950a1844ef8d3098ea290032aeb92e2e32c3"
"reference": "7c324e7011246f0064b055b62ab9c3921cf0a041"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/framework/zipball/57d1950a1844ef8d3098ea290032aeb92e2e32c3",
"reference": "57d1950a1844ef8d3098ea290032aeb92e2e32c3",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"url": "https://api.github.com/repos/top-think/framework/zipball/7c324e7011246f0064b055b62ab9c3921cf0a041",
"reference": "7c324e7011246f0064b055b62ab9c3921cf0a041",
"shasum": ""
},
"require": {
"ext-json": "*",
@ -4129,9 +3966,9 @@
"mockery/mockery": "^1.2",
"phpunit/phpunit": "^7.0"
},
"time": "2024-04-16T02:01:19+00:00",
"time": "2023-05-22T03:02:08+00:00",
"type": "library",
"installation-source": "dist",
"installation-source": "source",
"autoload": {
"files": [],
"psr-4": {
@ -4161,7 +3998,7 @@
],
"support": {
"issues": "https://github.com/top-think/framework/issues",
"source": "https://github.com/top-think/framework/tree/v6.1.5"
"source": "https://github.com/top-think/framework/tree/v6.1.3"
},
"install-path": "../topthink/framework"
},
@ -4178,13 +4015,7 @@
"type": "zip",
"url": "https://api.github.com/repos/top-think/think-filesystem/zipball/29f19f140a9267c717fecd7ccb22c84c2d72382e",
"reference": "29f19f140a9267c717fecd7ccb22c84c2d72382e",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"league/flysystem": "^1.1.4",
@ -4199,7 +4030,7 @@
},
"time": "2023-02-08T01:25:15+00:00",
"type": "library",
"installation-source": "dist",
"installation-source": "source",
"autoload": {
"psr-4": {
"think\\": "src"
@ -4251,7 +4082,7 @@
},
"time": "2025-04-07T06:55:59+00:00",
"type": "library",
"installation-source": "source",
"installation-source": "dist",
"autoload": {
"files": [
"src/helper.php"
@ -4279,30 +4110,24 @@
},
{
"name": "topthink/think-multi-app",
"version": "v1.1.1",
"version_normalized": "1.1.1.0",
"version": "v1.0.17",
"version_normalized": "1.0.17.0",
"source": {
"type": "git",
"url": "https://github.com/top-think/think-multi-app.git",
"reference": "f93c604d5cfac2b613756273224ee2f88e457b88"
"reference": "4055a6187296ac16c0bc7bbab4ed5d92f82f791c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/think-multi-app/zipball/f93c604d5cfac2b613756273224ee2f88e457b88",
"reference": "f93c604d5cfac2b613756273224ee2f88e457b88",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"url": "https://api.github.com/repos/top-think/think-multi-app/zipball/4055a6187296ac16c0bc7bbab4ed5d92f82f791c",
"reference": "4055a6187296ac16c0bc7bbab4ed5d92f82f791c",
"shasum": ""
},
"require": {
"php": ">=7.1.0",
"topthink/framework": "^6.0|^8.0"
},
"time": "2024-11-25T08:52:44+00:00",
"time": "2023-03-29T02:04:29+00:00",
"type": "library",
"extra": {
"think": {
@ -4311,7 +4136,7 @@
]
}
},
"installation-source": "dist",
"installation-source": "source",
"autoload": {
"psr-4": {
"think\\app\\": "src"
@ -4330,30 +4155,24 @@
"description": "thinkphp multi app support",
"support": {
"issues": "https://github.com/top-think/think-multi-app/issues",
"source": "https://github.com/top-think/think-multi-app/tree/v1.1.1"
"source": "https://github.com/top-think/think-multi-app/tree/v1.0.17"
},
"install-path": "../topthink/think-multi-app"
},
{
"name": "topthink/think-orm",
"version": "v2.0.62",
"version_normalized": "2.0.62.0",
"version": "v2.0.61",
"version_normalized": "2.0.61.0",
"source": {
"type": "git",
"url": "https://github.com/top-think/think-orm.git",
"reference": "e53bfea572a133039ad687077120de5521af617f"
"reference": "10528ebf4a5106b19c3bac9c6deae7a67ff49de6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/think-orm/zipball/e53bfea572a133039ad687077120de5521af617f",
"reference": "e53bfea572a133039ad687077120de5521af617f",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"url": "https://api.github.com/repos/top-think/think-orm/zipball/10528ebf4a5106b19c3bac9c6deae7a67ff49de6",
"reference": "10528ebf4a5106b19c3bac9c6deae7a67ff49de6",
"shasum": ""
},
"require": {
"ext-json": "*",
@ -4366,9 +4185,9 @@
"require-dev": {
"phpunit/phpunit": "^7|^8|^9.5"
},
"time": "2024-09-22T06:17:47+00:00",
"time": "2023-04-20T14:27:51+00:00",
"type": "library",
"installation-source": "dist",
"installation-source": "source",
"autoload": {
"files": [
"stubs/load_stubs.php"
@ -4394,7 +4213,7 @@
],
"support": {
"issues": "https://github.com/top-think/think-orm/issues",
"source": "https://github.com/top-think/think-orm/tree/v2.0.62"
"source": "https://github.com/top-think/think-orm/tree/v2.0.61"
},
"install-path": "../topthink/think-orm"
},
@ -4442,7 +4261,7 @@
]
}
},
"installation-source": "source",
"installation-source": "dist",
"autoload": {
"files": [
"src/common.php"
@ -4481,13 +4300,7 @@
"type": "zip",
"url": "https://api.github.com/repos/top-think/think-trace/zipball/136cd5d97e8bdb780e4b5c1637c588ed7ca3e142",
"reference": "136cd5d97e8bdb780e4b5c1637c588ed7ca3e142",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"php": ">=7.1.0",
@ -4497,15 +4310,15 @@
"type": "library",
"extra": {
"think": {
"config": {
"trace": "src/config.php"
},
"services": [
"think\\trace\\Service"
]
],
"config": {
"trace": "src/config.php"
}
}
},
"installation-source": "dist",
"installation-source": "source",
"autoload": {
"psr-4": {
"think\\trace\\": "src"
@ -4541,13 +4354,7 @@
"type": "zip",
"url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991",
"reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
"shasum": ""
},
"require": {
"ext-ctype": "*",

28
vendor/composer/installed.php

@ -3,7 +3,7 @@
'name' => 'topthink/think',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '2e9eff4ffb14a02509406f896085c64676d3c323',
'reference' => '2eab3499945d32d05b064575c56f2041a7c7e9de',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@ -281,9 +281,9 @@
'dev_requirement' => false,
),
'phpmailer/phpmailer' => array(
'pretty_version' => 'v6.9.3',
'version' => '6.9.3.0',
'reference' => '2f5c94fe7493efc213f643c23b1b1c249d40f47e',
'pretty_version' => 'v6.8.0',
'version' => '6.8.0.0',
'reference' => 'df16b615e371d81fb79e506277faea67a1be18f1',
'type' => 'library',
'install_path' => __DIR__ . '/../phpmailer/phpmailer',
'aliases' => array(),
@ -518,9 +518,9 @@
'dev_requirement' => true,
),
'topthink/framework' => array(
'pretty_version' => 'v6.1.5',
'version' => '6.1.5.0',
'reference' => '57d1950a1844ef8d3098ea290032aeb92e2e32c3',
'pretty_version' => 'v6.1.3',
'version' => '6.1.3.0',
'reference' => '7c324e7011246f0064b055b62ab9c3921cf0a041',
'type' => 'library',
'install_path' => __DIR__ . '/../topthink/framework',
'aliases' => array(),
@ -529,7 +529,7 @@
'topthink/think' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '2e9eff4ffb14a02509406f896085c64676d3c323',
'reference' => '2eab3499945d32d05b064575c56f2041a7c7e9de',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@ -554,18 +554,18 @@
'dev_requirement' => false,
),
'topthink/think-multi-app' => array(
'pretty_version' => 'v1.1.1',
'version' => '1.1.1.0',
'reference' => 'f93c604d5cfac2b613756273224ee2f88e457b88',
'pretty_version' => 'v1.0.17',
'version' => '1.0.17.0',
'reference' => '4055a6187296ac16c0bc7bbab4ed5d92f82f791c',
'type' => 'library',
'install_path' => __DIR__ . '/../topthink/think-multi-app',
'aliases' => array(),
'dev_requirement' => false,
),
'topthink/think-orm' => array(
'pretty_version' => 'v2.0.62',
'version' => '2.0.62.0',
'reference' => 'e53bfea572a133039ad687077120de5521af617f',
'pretty_version' => 'v2.0.61',
'version' => '2.0.61.0',
'reference' => '10528ebf4a5106b19c3bac9c6deae7a67ff49de6',
'type' => 'library',
'install_path' => __DIR__ . '/../topthink/think-orm',
'aliases' => array(),

9
vendor/guzzlehttp/promises/.editorconfig

@ -1,9 +0,0 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true

13
vendor/guzzlehttp/promises/.gitattributes

@ -1,13 +0,0 @@
.editorconfig export-ignore
.gitattributes export-ignore
/.github/ export-ignore
.gitignore export-ignore
/.php-cs-fixer.dist.php export-ignore
/phpstan-baseline.neon export-ignore
/phpstan.neon.dist export-ignore
/phpunit.xml.dist export-ignore
/psalm-baseline.xml export-ignore
/psalm.xml export-ignore
/tests/ export-ignore
/vendor-bin/ export-ignore
/Makefile export-ignore

2
vendor/guzzlehttp/promises/.github/.editorconfig

@ -1,2 +0,0 @@
[*.yml]
indent_size = 2

2
vendor/guzzlehttp/promises/.github/FUNDING.yml

@ -1,2 +0,0 @@
github: [Nyholm, GrahamCampbell]
tidelift: "packagist/guzzlehttp/promises"

14
vendor/guzzlehttp/promises/.github/stale.yml

@ -1,14 +0,0 @@
daysUntilStale: 120
daysUntilClose: 14
exemptLabels:
- lifecycle/keep-open
- lifecycle/ready-for-merge
# Label to use when marking an issue as stale
staleLabel: lifecycle/stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed after 2 weeks if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

21
vendor/guzzlehttp/promises/.github/workflows/checks.yml

@ -1,21 +0,0 @@
name: Checks
on:
push:
branches:
pull_request:
permissions:
contents: read
jobs:
composer-normalize:
name: Composer Normalize
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Composer normalize
uses: docker://ergebnis/composer-normalize-action

58
vendor/guzzlehttp/promises/.github/workflows/ci.yml

@ -1,58 +0,0 @@
name: CI
on:
push:
branches:
pull_request:
permissions:
contents: read
jobs:
build-lowest-version:
name: Build lowest version
runs-on: ubuntu-22.04
steps:
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: '7.2'
ini-values: error_reporting=E_ALL
coverage: 'none'
extensions: mbstring
- name: Checkout code
uses: actions/checkout@v4
- name: Install dependencies
run: composer update --no-interaction --prefer-stable --prefer-lowest --no-progress
- name: Run tests
run: vendor/bin/phpunit
build:
name: Build
runs-on: ubuntu-22.04
strategy:
max-parallel: 10
matrix:
php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4']
steps:
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
ini-values: error_reporting=E_ALL
coverage: 'none'
extensions: mbstring
- name: Checkout code
uses: actions/checkout@v4
- name: Install dependencies
run: composer update --no-interaction --no-progress
- name: Run tests
run: vendor/bin/phpunit

82
vendor/guzzlehttp/promises/.github/workflows/static.yml

@ -1,82 +0,0 @@
name: Static analysis
on:
push:
branches:
pull_request:
permissions:
contents: read
jobs:
phpstan:
name: PHPStan
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '7.4'
coverage: none
extensions: mbstring
- name: Download dependencies
run: composer update --no-interaction --no-progress
- name: Download PHPStan
run: composer bin phpstan update --no-interaction --no-progress
- name: Execute PHPStan
run: vendor/bin/phpstan analyze --no-progress
php-cs-fixer:
name: PHP-CS-Fixer
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '7.4'
coverage: none
extensions: mbstring
- name: Download dependencies
run: composer update --no-interaction --no-progress
- name: Download PHP CS Fixer
run: composer bin php-cs-fixer update --no-interaction --no-progress
- name: Execute PHP CS Fixer
run: vendor/bin/php-cs-fixer fix --diff --dry-run
psalm:
name: Psalm
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '7.4'
coverage: none
extensions: mbstring
- name: Download dependencies
run: composer update --no-interaction --no-progress
- name: Download Psalm
run: composer bin psalm update --no-interaction --no-progress
- name: Execute Psalm
run: vendor/bin/psalm.phar --no-progress --output-format=github

7
vendor/guzzlehttp/promises/.gitignore

@ -1,7 +0,0 @@
artifacts/
vendor/
composer.lock
phpunit.xml
.php-cs-fixer.php
.php-cs-fixer.cache
.phpunit.result.cache

28
vendor/guzzlehttp/promises/.php-cs-fixer.dist.php

@ -1,28 +0,0 @@
<?php
$config = (new PhpCsFixer\Config())
->setRiskyAllowed(true)
->setRules([
'@PHP71Migration:risky' => true,
'@PHPUnit75Migration:risky' => true,
'@PSR12:risky' => true,
'@Symfony' => true,
'global_namespace_import' => false,
'no_superfluous_phpdoc_tags' => [
'allow_mixed' => true,
],
'phpdoc_annotation_without_dot' => false,
'phpdoc_summary' => false,
'phpdoc_to_comment' => false,
'single_line_throw' => false,
'yoda_style' => false,
])
->setFinder(
PhpCsFixer\Finder::create()
->in(__DIR__.'/src')
->in(__DIR__.'/tests')
->name('*.php')
)
;
return $config;

13
vendor/guzzlehttp/promises/Makefile

@ -1,13 +0,0 @@
all: clean test
test:
vendor/bin/phpunit
coverage:
vendor/bin/phpunit --coverage-html=artifacts/coverage
view-coverage:
open artifacts/coverage/index.html
clean:
rm -rf artifacts/*

8
vendor/guzzlehttp/promises/phpstan-baseline.neon

@ -1,8 +0,0 @@
parameters:
ignoreErrors:
-
message: '#^Dead catch \- GuzzleHttp\\Promise\\RejectionException is never thrown in the try block\.$#'
identifier: catch.neverThrown
count: 1
path: src/Utils.php

7
vendor/guzzlehttp/promises/phpstan.neon.dist

@ -1,7 +0,0 @@
includes:
- phpstan-baseline.neon
parameters:
level: 5
paths:
- src

21
vendor/guzzlehttp/promises/phpunit.xml.dist

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
colors="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTestsThatDoNotTestAnything="true"
bootstrap="vendor/autoload.php"
>
<testsuites>
<testsuite name="GuzzleHttp Promise Test Suite">
<directory>tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>src/</directory>
<exclude>
<directory suffix="Interface.php">src/</directory>
</exclude>
</whitelist>
</filter>
</phpunit>

2
vendor/guzzlehttp/promises/psalm-baseline.xml

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="5.26.1@d747f6500b38ac4f7dfc5edbcae6e4b637d7add0"/>

18
vendor/guzzlehttp/promises/psalm.xml

@ -1,18 +0,0 @@
<?xml version="1.0"?>
<psalm
errorLevel="4"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
errorBaseline="psalm-baseline.xml"
findUnusedBaselineEntry="true"
findUnusedCode="false"
>
<projectFiles>
<directory name="src" />
<ignoreFiles>
<directory name="vendor" />
</ignoreFiles>
</projectFiles>
</psalm>

18
vendor/guzzlehttp/promises/tests/AggregateExceptionTest.php

@ -1,18 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Promise\Tests;
use GuzzleHttp\Promise\AggregateException;
use PHPUnit\Framework\TestCase;
class AggregateExceptionTest extends TestCase
{
public function testHasReason(): void
{
$e = new AggregateException('foo', ['baz', 'bar']);
$this->assertStringContainsString('foo', $e->getMessage());
$this->assertSame(['baz', 'bar'], $e->getReason());
}
}

115
vendor/guzzlehttp/promises/tests/CoroutineTest.php

@ -1,115 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Promise\Tests;
use GuzzleHttp\Promise\Coroutine;
use GuzzleHttp\Promise\Promise;
use GuzzleHttp\Promise\PromiseInterface;
use PHPUnit\Framework\TestCase;
use ReflectionClass;
class CoroutineTest extends TestCase
{
public function testReturnsCoroutine(): void
{
$fn = function () { yield 'foo'; };
$this->assertInstanceOf(Coroutine::class, Coroutine::of($fn));
}
/**
* @dataProvider promiseInterfaceMethodProvider
*
* @param string $method
* @param array $args
*/
public function testShouldProxyPromiseMethodsToResultPromise($method, $args = []): void
{
$coroutine = new Coroutine(function () { yield 0; });
$mockPromise = $this->getMockForAbstractClass(PromiseInterface::class);
$mockPromise->expects($this->once())->method($method)->with(...$args);
$resultPromiseProp = (new ReflectionClass(Coroutine::class))->getProperty('result');
$resultPromiseProp->setAccessible(true);
$resultPromiseProp->setValue($coroutine, $mockPromise);
$coroutine->{$method}(...$args);
}
public function promiseInterfaceMethodProvider()
{
return [
['then', [null, null]],
['otherwise', [function (): void {}]],
['wait', [true]],
['getState', []],
['resolve', [null]],
['reject', [null]],
];
}
public function testShouldCancelResultPromiseAndOutsideCurrentPromise(): void
{
$coroutine = new Coroutine(function () { yield 0; });
$mockPromises = [
'result' => $this->getMockForAbstractClass(PromiseInterface::class),
'currentPromise' => $this->getMockForAbstractClass(PromiseInterface::class),
];
foreach ($mockPromises as $propName => $mockPromise) {
/**
* @var $mockPromise \PHPUnit_Framework_MockObject_MockObject
*/
$mockPromise->expects($this->once())
->method('cancel')
->with();
$promiseProp = (new ReflectionClass(Coroutine::class))->getProperty($propName);
$promiseProp->setAccessible(true);
$promiseProp->setValue($coroutine, $mockPromise);
}
$coroutine->cancel();
}
public function testWaitShouldResolveChainedCoroutines(): void
{
$promisor = function () {
return Coroutine::of(function () {
yield $promise = new Promise(function () use (&$promise): void {
$promise->resolve(1);
});
});
};
$promise = $promisor()->then($promisor)->then($promisor);
$this->assertSame(1, $promise->wait());
}
public function testWaitShouldHandleIntermediateErrors(): void
{
$promise = Coroutine::of(function () {
yield $promise = new Promise(function () use (&$promise): void {
$promise->resolve(1);
});
})
->then(function () {
return Coroutine::of(function () {
yield $promise = new Promise(function () use (&$promise): void {
$promise->reject(new \Exception());
});
});
})
->otherwise(function (?\Exception $error = null) {
if (!$error) {
self::fail('Error did not propagate.');
}
return 3;
});
$this->assertSame(3, $promise->wait());
}
}

58
vendor/guzzlehttp/promises/tests/CreateTest.php

@ -1,58 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Promise\Tests;
use GuzzleHttp\Promise as P;
use GuzzleHttp\Promise\FulfilledPromise;
use GuzzleHttp\Promise\Promise;
use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Promise\RejectedPromise;
use PHPUnit\Framework\TestCase;
class CreateTest extends TestCase
{
public function testCreatesPromiseForValue(): void
{
$p = P\Create::promiseFor('foo');
$this->assertInstanceOf(FulfilledPromise::class, $p);
}
public function testReturnsPromiseForPromise(): void
{
$p = new Promise();
$this->assertSame($p, P\Create::promiseFor($p));
}
public function testReturnsPromiseForThennable(): void
{
$p = new Thennable();
$wrapped = P\Create::promiseFor($p);
$this->assertNotSame($p, $wrapped);
$this->assertInstanceOf(PromiseInterface::class, $wrapped);
$p->resolve('foo');
P\Utils::queue()->run();
$this->assertSame('foo', $wrapped->wait());
}
public function testReturnsRejection(): void
{
$p = P\Create::rejectionFor('fail');
$this->assertInstanceOf(RejectedPromise::class, $p);
$this->assertSame('fail', PropertyHelper::get($p, 'reason'));
}
public function testReturnsPromisesAsIsInRejectionFor(): void
{
$a = new Promise();
$b = P\Create::rejectionFor($a);
$this->assertSame($a, $b);
}
public function testIterForReturnsIterator(): void
{
$iter = new \ArrayIterator();
$this->assertSame($iter, P\Create::iterFor($iter));
}
}

433
vendor/guzzlehttp/promises/tests/EachPromiseTest.php

@ -1,433 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Promise\Tests;
use GuzzleHttp\Promise as P;
use GuzzleHttp\Promise\EachPromise;
use GuzzleHttp\Promise\FulfilledPromise;
use GuzzleHttp\Promise\Promise;
use GuzzleHttp\Promise\RejectedPromise;
use PHPUnit\Framework\TestCase;
/**
* @covers \GuzzleHttp\Promise\EachPromise
*/
class EachPromiseTest extends TestCase
{
public function testReturnsSameInstance(): void
{
$each = new EachPromise([], ['concurrency' => 100]);
$this->assertSame($each->promise(), $each->promise());
}
public function testResolvesInCaseOfAnEmptyList(): void
{
$promises = [];
$each = new EachPromise($promises);
$p = $each->promise();
$this->assertNull($p->wait());
$this->assertTrue(P\Is::fulfilled($p));
}
public function testResolvesInCaseOfAnEmptyListAndInvokesFulfilled(): void
{
$promises = [];
$each = new EachPromise($promises);
$p = $each->promise();
$onFulfilledCalled = false;
$onRejectedCalled = false;
$p->then(
function () use (&$onFulfilledCalled): void {
$onFulfilledCalled = true;
},
function () use (&$onRejectedCalled): void {
$onRejectedCalled = true;
}
);
$this->assertNull($p->wait());
$this->assertTrue(P\Is::fulfilled($p));
$this->assertTrue($onFulfilledCalled);
$this->assertFalse($onRejectedCalled);
}
public function testInvokesAllPromises(): void
{
$promises = [new Promise(), new Promise(), new Promise()];
$called = [];
$each = new EachPromise($promises, [
'fulfilled' => function ($value) use (&$called): void {
$called[] = $value;
},
]);
$p = $each->promise();
$promises[0]->resolve('a');
$promises[1]->resolve('c');
$promises[2]->resolve('b');
P\Utils::queue()->run();
$this->assertSame(['a', 'c', 'b'], $called);
$this->assertTrue(P\Is::fulfilled($p));
}
public function testIsWaitable(): void
{
$a = $this->createSelfResolvingPromise('a');
$b = $this->createSelfResolvingPromise('b');
$called = [];
$each = new EachPromise([$a, $b], [
'fulfilled' => function ($value) use (&$called): void { $called[] = $value; },
]);
$p = $each->promise();
$this->assertNull($p->wait());
$this->assertTrue(P\Is::fulfilled($p));
$this->assertSame(['a', 'b'], $called);
}
public function testCanResolveBeforeConsumingAll(): void
{
$called = 0;
$a = $this->createSelfResolvingPromise('a');
$b = new Promise(function (): void { $this->fail(); });
$each = new EachPromise([$a, $b], [
'fulfilled' => function ($value, $idx, Promise $aggregate) use (&$called): void {
$this->assertSame($idx, 0);
$this->assertSame('a', $value);
$aggregate->resolve(null);
++$called;
},
'rejected' => function (\Exception $reason): void {
$this->fail($reason->getMessage());
},
]);
$p = $each->promise();
$p->wait();
$this->assertNull($p->wait());
$this->assertSame(1, $called);
$this->assertTrue(P\Is::fulfilled($a));
$this->assertTrue(P\Is::pending($b));
// Resolving $b has no effect on the aggregate promise.
$b->resolve('foo');
$this->assertSame(1, $called);
}
public function testLimitsPendingPromises(): void
{
$pending = [new Promise(), new Promise(), new Promise(), new Promise()];
$promises = new \ArrayIterator($pending);
$each = new EachPromise($promises, ['concurrency' => 2]);
$p = $each->promise();
$this->assertCount(2, PropertyHelper::get($each, 'pending'));
$pending[0]->resolve('a');
$this->assertCount(2, PropertyHelper::get($each, 'pending'));
$this->assertTrue($promises->valid());
$pending[1]->resolve('b');
P\Utils::queue()->run();
$this->assertCount(2, PropertyHelper::get($each, 'pending'));
$this->assertTrue($promises->valid());
$promises[2]->resolve('c');
P\Utils::queue()->run();
$this->assertCount(1, PropertyHelper::get($each, 'pending'));
$this->assertTrue(P\Is::pending($p));
$promises[3]->resolve('d');
P\Utils::queue()->run();
$this->assertNull(PropertyHelper::get($each, 'pending'));
$this->assertTrue(P\Is::fulfilled($p));
$this->assertFalse($promises->valid());
}
public function testDynamicallyLimitsPendingPromises(): void
{
$calls = [];
$pendingFn = function ($count) use (&$calls) {
$calls[] = $count;
return 2;
};
$pending = [new Promise(), new Promise(), new Promise(), new Promise()];
$promises = new \ArrayIterator($pending);
$each = new EachPromise($promises, ['concurrency' => $pendingFn]);
$p = $each->promise();
$this->assertCount(2, PropertyHelper::get($each, 'pending'));
$pending[0]->resolve('a');
$this->assertCount(2, PropertyHelper::get($each, 'pending'));
$this->assertTrue($promises->valid());
$pending[1]->resolve('b');
$this->assertCount(2, PropertyHelper::get($each, 'pending'));
P\Utils::queue()->run();
$this->assertTrue($promises->valid());
$promises[2]->resolve('c');
P\Utils::queue()->run();
$this->assertCount(1, PropertyHelper::get($each, 'pending'));
$this->assertTrue(P\Is::pending($p));
$promises[3]->resolve('d');
P\Utils::queue()->run();
$this->assertNull(PropertyHelper::get($each, 'pending'));
$this->assertTrue(P\Is::fulfilled($p));
$this->assertSame([0, 1, 1, 1], $calls);
$this->assertFalse($promises->valid());
}
public function testClearsReferencesWhenResolved(): void
{
$called = false;
$a = new Promise(function () use (&$a, &$called): void {
$a->resolve('a');
$called = true;
});
$each = new EachPromise([$a], [
'concurrency' => function () { return 1; },
'fulfilled' => function (): void {},
'rejected' => function (): void {},
]);
$each->promise()->wait();
$this->assertNull(PropertyHelper::get($each, 'onFulfilled'));
$this->assertNull(PropertyHelper::get($each, 'onRejected'));
$this->assertNull(PropertyHelper::get($each, 'iterable'));
$this->assertNull(PropertyHelper::get($each, 'pending'));
$this->assertNull(PropertyHelper::get($each, 'concurrency'));
$this->assertTrue($called);
}
public function testCanBeCancelled(): void
{
$called = false;
$a = new FulfilledPromise('a');
$b = new Promise(function () use (&$called): void { $called = true; });
$each = new EachPromise([$a, $b], [
'fulfilled' => function ($value, $idx, Promise $aggregate): void {
$aggregate->cancel();
},
'rejected' => function ($reason) use (&$called): void {
$called = true;
},
]);
$p = $each->promise();
$p->wait(false);
$this->assertTrue(P\Is::fulfilled($a));
$this->assertTrue(P\Is::pending($b));
$this->assertTrue(P\Is::rejected($p));
$this->assertFalse($called);
}
public function testDoesNotBlowStackWithFulfilledPromises(): void
{
$pending = [];
for ($i = 0; $i < 100; ++$i) {
$pending[] = new FulfilledPromise($i);
}
$values = [];
$each = new EachPromise($pending, [
'fulfilled' => function ($value) use (&$values): void {
$values[] = $value;
},
]);
$called = false;
$each->promise()->then(function () use (&$called): void {
$called = true;
});
$this->assertFalse($called);
P\Utils::queue()->run();
$this->assertTrue($called);
$this->assertSame(range(0, 99), $values);
}
public function testDoesNotBlowStackWithRejectedPromises(): void
{
$pending = [];
for ($i = 0; $i < 100; ++$i) {
$pending[] = new RejectedPromise($i);
}
$values = [];
$each = new EachPromise($pending, [
'rejected' => function ($value) use (&$values): void {
$values[] = $value;
},
]);
$called = false;
$each->promise()->then(
function () use (&$called): void { $called = true; },
function (): void { $this->fail('Should not have rejected.'); }
);
$this->assertFalse($called);
P\Utils::queue()->run();
$this->assertTrue($called);
$this->assertSame(range(0, 99), $values);
}
public function testReturnsPromiseForWhatever(): void
{
$called = [];
$arr = ['a', 'b'];
$each = new EachPromise($arr, [
'fulfilled' => function ($v) use (&$called): void { $called[] = $v; },
]);
$p = $each->promise();
$this->assertNull($p->wait());
$this->assertSame(['a', 'b'], $called);
}
public function testRejectsAggregateWhenNextThrows(): void
{
$iter = function () {
yield 'a';
throw new \Exception('Failure');
};
$each = new EachPromise($iter());
$p = $each->promise();
$e = null;
$received = null;
$p->then(null, function ($reason) use (&$e): void { $e = $reason; });
P\Utils::queue()->run();
$this->assertInstanceOf(\Exception::class, $e);
$this->assertSame('Failure', $e->getMessage());
}
public function testDoesNotCallNextOnIteratorUntilNeededWhenWaiting(): void
{
$results = [];
$values = [10];
$remaining = 9;
$iter = function () use (&$values) {
while ($value = array_pop($values)) {
yield $value;
}
};
$each = new EachPromise($iter(), [
'concurrency' => 1,
'fulfilled' => function ($r) use (&$results, &$values, &$remaining): void {
$results[] = $r;
if ($remaining > 0) {
$values[] = $remaining--;
}
},
]);
$each->promise()->wait();
$this->assertSame(range(10, 1), $results);
}
public function testDoesNotCallNextOnIteratorUntilNeededWhenAsync(): void
{
$firstPromise = new Promise();
$pending = [$firstPromise];
$values = [$firstPromise];
$results = [];
$remaining = 9;
$iter = function () use (&$values) {
while ($value = array_pop($values)) {
yield $value;
}
};
$each = new EachPromise($iter(), [
'concurrency' => 1,
'fulfilled' => function ($r) use (&$results, &$values, &$remaining, &$pending): void {
$results[] = $r;
if ($remaining-- > 0) {
$pending[] = $values[] = new Promise();
}
},
]);
$i = 0;
$each->promise();
while ($promise = array_pop($pending)) {
$promise->resolve($i++);
P\Utils::queue()->run();
}
$this->assertSame(range(0, 9), $results);
}
private function createSelfResolvingPromise($value)
{
$p = new Promise(function () use (&$p, $value): void {
$p->resolve($value);
});
$trickCsFixer = true;
return $p;
}
public function testMutexPreventsGeneratorRecursion(): void
{
if (defined('HHVM_VERSION')) {
$this->markTestIncomplete('Broken on HHVM.');
}
$results = $promises = [];
for ($i = 0; $i < 20; ++$i) {
$p = $this->createSelfResolvingPromise($i);
$pending[] = $p;
$promises[] = $p;
}
$iter = function () use (&$promises, &$pending) {
foreach ($promises as $promise) {
// Resolve a promises, which will trigger the then() function,
// which would cause the EachPromise to try to add more
// promises to the queue. Without a lock, this would trigger
// a "Cannot resume an already running generator" fatal error.
if ($p = array_pop($pending)) {
$p->wait();
}
yield $promise;
}
};
$each = new EachPromise($iter(), [
'concurrency' => 5,
'fulfilled' => function ($r) use (&$results, &$pending): void {
$results[] = $r;
},
]);
$each->promise()->wait();
$this->assertCount(20, $results);
}
public function testIteratorWithSameKey(): void
{
if (defined('HHVM_VERSION')) {
$this->markTestIncomplete('Broken on HHVM.');
}
$iter = function () {
yield 'foo' => $this->createSelfResolvingPromise(1);
yield 'foo' => $this->createSelfResolvingPromise(2);
yield 1 => $this->createSelfResolvingPromise(3);
yield 1 => $this->createSelfResolvingPromise(4);
};
$called = 0;
$each = new EachPromise($iter(), [
'fulfilled' => function ($value, $idx, Promise $aggregate) use (&$called): void {
++$called;
if ($value < 3) {
$this->assertSame('foo', $idx);
} else {
$this->assertSame(1, $idx);
}
},
]);
$each->promise()->wait();
$this->assertSame(4, $called);
}
public function testIsWaitableWhenLimited(): void
{
$promises = [
$this->createSelfResolvingPromise('a'),
$this->createSelfResolvingPromise('c'),
$this->createSelfResolvingPromise('b'),
$this->createSelfResolvingPromise('d'),
];
$called = [];
$each = new EachPromise($promises, [
'concurrency' => 2,
'fulfilled' => function ($value) use (&$called): void {
$called[] = $value;
},
]);
$p = $each->promise();
$this->assertNull($p->wait());
$this->assertSame(['a', 'c', 'b', 'd'], $called);
$this->assertTrue(P\Is::fulfilled($p));
}
}

36
vendor/guzzlehttp/promises/tests/EachTest.php

@ -1,36 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Promise\Tests;
use GuzzleHttp\Promise as P;
use GuzzleHttp\Promise\FulfilledPromise;
use GuzzleHttp\Promise\Promise;
use GuzzleHttp\Promise\RejectedPromise;
use PHPUnit\Framework\TestCase;
class EachTest extends TestCase
{
public function testCallsEachLimit(): void
{
$p = new Promise();
$aggregate = P\Each::ofLimit($p, 2);
$p->resolve('a');
P\Utils::queue()->run();
$this->assertTrue(P\Is::fulfilled($aggregate));
}
public function testEachLimitAllRejectsOnFailure(): void
{
$p = [new FulfilledPromise('a'), new RejectedPromise('b')];
$aggregate = P\Each::ofLimitAll($p, 2);
P\Utils::queue()->run();
$this->assertTrue(P\Is::rejected($aggregate));
$result = P\Utils::inspect($aggregate);
$this->assertSame('b', $result['reason']);
}
}

115
vendor/guzzlehttp/promises/tests/FulfilledPromiseTest.php

@ -1,115 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Promise\Tests;
use GuzzleHttp\Promise as P;
use GuzzleHttp\Promise\FulfilledPromise;
use GuzzleHttp\Promise\Promise;
use PHPUnit\Framework\TestCase;
/**
* @covers \GuzzleHttp\Promise\FulfilledPromise
*/
class FulfilledPromiseTest extends TestCase
{
public function testReturnsValueWhenWaitedUpon(): void
{
$p = new FulfilledPromise('foo');
$this->assertTrue(P\Is::fulfilled($p));
$this->assertSame('foo', $p->wait(true));
}
public function testCannotCancel(): void
{
$p = new FulfilledPromise('foo');
$this->assertTrue(P\Is::fulfilled($p));
$p->cancel();
$this->assertSame('foo', $p->wait());
}
/**
* @expectedExceptionMessage Cannot resolve a fulfilled promise
*/
public function testCannotResolve(): void
{
$this->expectException(\LogicException::class);
$p = new FulfilledPromise('foo');
$p->resolve('bar');
}
/**
* @expectedExceptionMessage Cannot reject a fulfilled promise
*/
public function testCannotReject(): void
{
$this->expectException(\LogicException::class);
$p = new FulfilledPromise('foo');
$p->reject('bar');
}
public function testCanResolveWithSameValue(): void
{
$p = new FulfilledPromise('foo');
$p->resolve('foo');
$this->assertSame('foo', $p->wait());
}
public function testCannotResolveWithPromise(): void
{
$this->expectException(\InvalidArgumentException::class);
new FulfilledPromise(new Promise());
}
public function testReturnsSelfWhenNoOnFulfilled(): void
{
$p = new FulfilledPromise('a');
$this->assertSame($p, $p->then());
}
public function testAsynchronouslyInvokesOnFulfilled(): void
{
$p = new FulfilledPromise('a');
$r = null;
$f = function ($d) use (&$r): void { $r = $d; };
$p2 = $p->then($f);
$this->assertNotSame($p, $p2);
$this->assertNull($r);
P\Utils::queue()->run();
$this->assertSame('a', $r);
}
public function testReturnsNewRejectedWhenOnFulfilledFails(): void
{
$p = new FulfilledPromise('a');
$f = function (): void { throw new \Exception('b'); };
$p2 = $p->then($f);
$this->assertNotSame($p, $p2);
try {
$p2->wait();
$this->fail();
} catch (\Exception $e) {
$this->assertSame('b', $e->getMessage());
}
}
public function testOtherwiseIsSugarForRejections(): void
{
$c = null;
$p = new FulfilledPromise('foo');
$p->otherwise(function ($v) use (&$c): void { $c = $v; });
$this->assertNull($c);
}
public function testDoesNotTryToFulfillTwiceDuringTrampoline(): void
{
$fp = new FulfilledPromise('a');
$t1 = $fp->then(function ($v) { return $v.' b'; });
$t1->resolve('why!');
$this->assertSame('why!', $t1->wait());
}
}

42
vendor/guzzlehttp/promises/tests/IsTest.php

@ -1,42 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Promise\Tests;
use GuzzleHttp\Promise as P;
use GuzzleHttp\Promise\FulfilledPromise;
use GuzzleHttp\Promise\Promise;
use GuzzleHttp\Promise\RejectedPromise;
use PHPUnit\Framework\TestCase;
class IsTest extends TestCase
{
public function testKnowsIfFulfilled(): void
{
$p = new FulfilledPromise(null);
$this->assertTrue(P\Is::fulfilled($p));
$this->assertFalse(P\Is::rejected($p));
}
public function testKnowsIfRejected(): void
{
$p = new RejectedPromise(null);
$this->assertTrue(P\Is::rejected($p));
$this->assertFalse(P\Is::fulfilled($p));
}
public function testKnowsIfSettled(): void
{
$p = new RejectedPromise(null);
$this->assertTrue(P\Is::settled($p));
$this->assertFalse(P\Is::pending($p));
}
public function testKnowsIfPending(): void
{
$p = new Promise();
$this->assertFalse(P\Is::settled($p));
$this->assertTrue(P\Is::pending($p));
}
}

51
vendor/guzzlehttp/promises/tests/NotPromiseInstance.php

@ -1,51 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Promise\Tests;
use GuzzleHttp\Promise\Promise;
use GuzzleHttp\Promise\PromiseInterface;
class NotPromiseInstance extends Thennable implements PromiseInterface
{
private $nextPromise;
public function __construct()
{
$this->nextPromise = new Promise();
}
public function then(?callable $res = null, ?callable $rej = null): PromiseInterface
{
return $this->nextPromise->then($res, $rej);
}
public function otherwise(callable $onRejected): PromiseInterface
{
return $this->then($onRejected);
}
public function resolve($value): void
{
$this->nextPromise->resolve($value);
}
public function reject($reason): void
{
$this->nextPromise->reject($reason);
}
public function wait(bool $unwrap = true, ?bool $defaultResolution = null): void
{
}
public function cancel(): void
{
}
public function getState(): string
{
return $this->nextPromise->getState();
}
}

773
vendor/guzzlehttp/promises/tests/PromiseTest.php

@ -1,773 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Promise\Tests;
use GuzzleHttp\Promise as P;
use GuzzleHttp\Promise\CancellationException;
use GuzzleHttp\Promise\FulfilledPromise;
use GuzzleHttp\Promise\Promise;
use GuzzleHttp\Promise\RejectedPromise;
use GuzzleHttp\Promise\RejectionException;
use PHPUnit\Framework\TestCase;
/**
* @covers \GuzzleHttp\Promise\Promise
*/
class PromiseTest extends TestCase
{
public function testCannotResolveNonPendingPromise(): void
{
$this->expectException(\LogicException::class);
$this->expectExceptionMessage('The promise is already fulfilled');
$p = new Promise();
$p->resolve('foo');
$p->resolve('bar');
$this->assertSame('foo', $p->wait());
}
public function testCanResolveWithSameValue(): void
{
$p = new Promise();
$p->resolve('foo');
$p->resolve('foo');
$this->assertSame('foo', $p->wait());
}
public function testCannotRejectNonPendingPromise(): void
{
$this->expectException(\LogicException::class);
$this->expectExceptionMessage('Cannot change a fulfilled promise to rejected');
$p = new Promise();
$p->resolve('foo');
$p->reject('bar');
$this->assertSame('foo', $p->wait());
}
public function testCanRejectWithSameValue(): void
{
$p = new Promise();
$p->reject('foo');
$p->reject('foo');
$this->assertTrue(P\Is::rejected($p));
}
public function testCannotRejectResolveWithSameValue(): void
{
$this->expectException(\LogicException::class);
$this->expectExceptionMessage('Cannot change a fulfilled promise to rejected');
$p = new Promise();
$p->resolve('foo');
$p->reject('foo');
}
public function testInvokesWaitFunction(): void
{
$p = new Promise(function () use (&$p): void {
$p->resolve('10');
});
$this->assertSame('10', $p->wait());
}
public function testRejectsAndThrowsWhenWaitFailsToResolve(): void
{
$this->expectException(RejectionException::class);
$this->expectExceptionMessage('The promise was rejected with reason: Invoking the wait callback did not resolve the promise');
$p = new Promise(function (): void {});
$p->wait();
}
public function testThrowsWhenUnwrapIsRejectedWithNonException(): void
{
$this->expectException(RejectionException::class);
$this->expectExceptionMessage('The promise was rejected with reason: foo');
$p = new Promise(function () use (&$p): void {
$p->reject('foo');
});
$p->wait();
}
public function testThrowsWhenUnwrapIsRejectedWithException(): void
{
$this->expectException(\UnexpectedValueException::class);
$this->expectExceptionMessage('foo');
$e = new \UnexpectedValueException('foo');
$p = new Promise(function () use (&$p, $e): void {
$p->reject($e);
});
$p->wait();
}
public function testDoesNotUnwrapExceptionsWhenDisabled(): void
{
$p = new Promise(function () use (&$p): void {
$p->reject('foo');
});
$this->assertTrue(P\Is::pending($p));
$p->wait(false);
$this->assertTrue(P\Is::rejected($p));
}
public function testRejectsSelfWhenWaitThrows(): void
{
$e = new \UnexpectedValueException('foo');
$p = new Promise(function () use ($e): void {
throw $e;
});
try {
$p->wait();
$this->fail();
} catch (\UnexpectedValueException $e) {
$this->assertTrue(P\Is::rejected($p));
}
}
public function testWaitsOnNestedPromises(): void
{
$p = new Promise(function () use (&$p): void {
$p->resolve('_');
});
$p2 = new Promise(function () use (&$p2): void {
$p2->resolve('foo');
});
$p3 = $p->then(function () use ($p2) {
return $p2;
});
$this->assertSame('foo', $p3->wait());
}
public function testThrowsWhenWaitingOnPromiseWithNoWaitFunction(): void
{
$this->expectException(RejectionException::class);
$p = new Promise();
$p->wait();
}
public function testThrowsWaitExceptionAfterPromiseIsResolved(): void
{
$p = new Promise(function () use (&$p): void {
$p->reject('Foo!');
throw new \Exception('Bar?');
});
try {
$p->wait();
$this->fail();
} catch (\Exception $e) {
$this->assertSame('Bar?', $e->getMessage());
}
}
public function testGetsActualWaitValueFromThen(): void
{
$p = new Promise(function () use (&$p): void {
$p->reject('Foo!');
});
$p2 = $p->then(null, function ($reason) {
return new RejectedPromise([$reason]);
});
try {
$p2->wait();
$this->fail('Should have thrown');
} catch (RejectionException $e) {
$this->assertSame(['Foo!'], $e->getReason());
}
}
public function testWaitBehaviorIsBasedOnLastPromiseInChain(): void
{
$p3 = new Promise(function () use (&$p3): void {
$p3->resolve('Whoop');
});
$p2 = new Promise(function () use (&$p2, $p3): void {
$p2->reject($p3);
});
$p = new Promise(function () use (&$p, $p2): void {
$p->reject($p2);
});
$this->assertSame('Whoop', $p->wait());
}
public function testWaitsOnAPromiseChainEvenWhenNotUnwrapped(): void
{
$p2 = new Promise(function () use (&$p2): void {
$p2->reject('Fail');
});
$p = new Promise(function () use ($p2, &$p): void {
$p->resolve($p2);
});
$p->wait(false);
$this->assertTrue(P\Is::rejected($p2));
}
public function testCannotCancelNonPending(): void
{
$p = new Promise();
$p->resolve('foo');
$p->cancel();
$this->assertTrue(P\Is::fulfilled($p));
}
public function testCancelsPromiseWhenNoCancelFunction(): void
{
$this->expectException(CancellationException::class);
$p = new Promise();
$p->cancel();
$this->assertTrue(P\Is::rejected($p));
$p->wait();
}
public function testCancelsPromiseWithCancelFunction(): void
{
$called = false;
$p = new Promise(null, function () use (&$called): void {
$called = true;
});
$p->cancel();
$this->assertTrue(P\Is::rejected($p));
$this->assertTrue($called);
}
public function testCancelsUppermostPendingPromise(): void
{
$called = false;
$p1 = new Promise(null, function () use (&$called): void {
$called = true;
});
$p2 = $p1->then(function (): void {});
$p3 = $p2->then(function (): void {});
$p4 = $p3->then(function (): void {});
$p3->cancel();
$this->assertTrue(P\Is::rejected($p1));
$this->assertTrue(P\Is::rejected($p2));
$this->assertTrue(P\Is::rejected($p3));
$this->assertTrue(P\Is::pending($p4));
$this->assertTrue($called);
try {
$p3->wait();
$this->fail();
} catch (CancellationException $e) {
$this->assertStringContainsString('cancelled', $e->getMessage());
}
try {
$p4->wait();
$this->fail();
} catch (CancellationException $e) {
$this->assertStringContainsString('cancelled', $e->getMessage());
}
$this->assertTrue(P\Is::rejected($p4));
}
public function testCancelsChildPromises(): void
{
$called1 = $called2 = $called3 = false;
$p1 = new Promise(null, function () use (&$called1): void {
$called1 = true;
});
$p2 = new Promise(null, function () use (&$called2): void {
$called2 = true;
});
$p3 = new Promise(null, function () use (&$called3): void {
$called3 = true;
});
$p4 = $p2->then(function () use ($p3) {
return $p3;
});
$p5 = $p4->then(function (): void {
$this->fail();
});
$p4->cancel();
$this->assertTrue(P\Is::pending($p1));
$this->assertTrue(P\Is::rejected($p2));
$this->assertTrue(P\Is::pending($p3));
$this->assertTrue(P\Is::rejected($p4));
$this->assertTrue(P\Is::pending($p5));
$this->assertFalse($called1);
$this->assertTrue($called2);
$this->assertFalse($called3);
}
public function testRejectsPromiseWhenCancelFails(): void
{
$called = false;
$p = new Promise(null, function () use (&$called): void {
$called = true;
throw new \Exception('e');
});
$p->cancel();
$this->assertTrue(P\Is::rejected($p));
$this->assertTrue($called);
try {
$p->wait();
$this->fail();
} catch (\Exception $e) {
$this->assertSame('e', $e->getMessage());
}
}
public function testCreatesPromiseWhenFulfilledAfterThen(): void
{
$p = new Promise();
$carry = null;
$p2 = $p->then(function ($v) use (&$carry): void {
$carry = $v;
});
$this->assertNotSame($p, $p2);
$p->resolve('foo');
P\Utils::queue()->run();
$this->assertSame('foo', $carry);
}
public function testCreatesPromiseWhenFulfilledBeforeThen(): void
{
$p = new Promise();
$p->resolve('foo');
$carry = null;
$p2 = $p->then(function ($v) use (&$carry): void {
$carry = $v;
});
$this->assertNotSame($p, $p2);
$this->assertNull($carry);
P\Utils::queue()->run();
$this->assertSame('foo', $carry);
}
public function testCreatesPromiseWhenFulfilledWithNoCallback(): void
{
$p = new Promise();
$p->resolve('foo');
$p2 = $p->then();
$this->assertNotSame($p, $p2);
$this->assertInstanceOf(FulfilledPromise::class, $p2);
}
public function testCreatesPromiseWhenRejectedAfterThen(): void
{
$p = new Promise();
$carry = null;
$p2 = $p->then(null, function ($v) use (&$carry): void {
$carry = $v;
});
$this->assertNotSame($p, $p2);
$p->reject('foo');
P\Utils::queue()->run();
$this->assertSame('foo', $carry);
}
public function testCreatesPromiseWhenRejectedBeforeThen(): void
{
$p = new Promise();
$p->reject('foo');
$carry = null;
$p2 = $p->then(null, function ($v) use (&$carry): void {
$carry = $v;
});
$this->assertNotSame($p, $p2);
$this->assertNull($carry);
P\Utils::queue()->run();
$this->assertSame('foo', $carry);
}
public function testCreatesPromiseWhenRejectedWithNoCallback(): void
{
$p = new Promise();
$p->reject('foo');
$p2 = $p->then();
$this->assertNotSame($p, $p2);
$this->assertInstanceOf(RejectedPromise::class, $p2);
}
public function testInvokesWaitFnsForThens(): void
{
$p = new Promise(function () use (&$p): void {
$p->resolve('a');
});
$p2 = $p
->then(function ($v) {
return $v.'-1-';
})
->then(function ($v) {
return $v.'2';
});
$this->assertSame('a-1-2', $p2->wait());
}
public function testStacksThenWaitFunctions(): void
{
$p1 = new Promise(function () use (&$p1): void {
$p1->resolve('a');
});
$p2 = new Promise(function () use (&$p2): void {
$p2->resolve('b');
});
$p3 = new Promise(function () use (&$p3): void {
$p3->resolve('c');
});
$p4 = $p1
->then(function () use ($p2) {
return $p2;
})
->then(function () use ($p3) {
return $p3;
});
$this->assertSame('c', $p4->wait());
}
public function testForwardsFulfilledDownChainBetweenGaps(): void
{
$p = new Promise();
$r = $r2 = null;
$p->then(null, null)
->then(function ($v) use (&$r) {
$r = $v;
return $v.'2';
})
->then(function ($v) use (&$r2): void {
$r2 = $v;
});
$p->resolve('foo');
P\Utils::queue()->run();
$this->assertSame('foo', $r);
$this->assertSame('foo2', $r2);
}
public function testForwardsRejectedPromisesDownChainBetweenGaps(): void
{
$p = new Promise();
$r = $r2 = null;
$p->then(null, null)
->then(null, function ($v) use (&$r) {
$r = $v;
return $v.'2';
})
->then(function ($v) use (&$r2): void {
$r2 = $v;
});
$p->reject('foo');
P\Utils::queue()->run();
$this->assertSame('foo', $r);
$this->assertSame('foo2', $r2);
}
public function testForwardsThrownPromisesDownChainBetweenGaps(): void
{
$e = new \Exception();
$p = new Promise();
$r = $r2 = null;
$p->then(null, null)
->then(null, function ($v) use (&$r, $e): void {
$r = $v;
throw $e;
})
->then(
null,
function ($v) use (&$r2): void {
$r2 = $v;
}
);
$p->reject('foo');
P\Utils::queue()->run();
$this->assertSame('foo', $r);
$this->assertSame($e, $r2);
}
public function testForwardsReturnedRejectedPromisesDownChainBetweenGaps(): void
{
$p = new Promise();
$rejected = new RejectedPromise('bar');
$r = $r2 = null;
$p->then(null, null)
->then(null, function ($v) use (&$r, $rejected) {
$r = $v;
return $rejected;
})
->then(
null,
function ($v) use (&$r2): void {
$r2 = $v;
}
);
$p->reject('foo');
P\Utils::queue()->run();
$this->assertSame('foo', $r);
$this->assertSame('bar', $r2);
try {
$p->wait();
} catch (RejectionException $e) {
$this->assertSame('foo', $e->getReason());
}
}
public function testForwardsHandlersToNextPromise(): void
{
$p = new Promise();
$p2 = new Promise();
$resolved = null;
$p
->then(function ($v) use ($p2) {
return $p2;
})
->then(function ($value) use (&$resolved): void {
$resolved = $value;
});
$p->resolve('a');
$p2->resolve('b');
P\Utils::queue()->run();
$this->assertSame('b', $resolved);
}
public function testRemovesReferenceFromChildWhenParentWaitedUpon(): void
{
$r = null;
$p = new Promise(function () use (&$p): void {
$p->resolve('a');
});
$p2 = new Promise(function () use (&$p2): void {
$p2->resolve('b');
});
$pb = $p->then(
function ($v) use ($p2, &$r) {
$r = $v;
return $p2;
}
)
->then(function ($v) {
return $v.'.';
});
$this->assertSame('a', $p->wait());
$this->assertSame('b', $p2->wait());
$this->assertSame('b.', $pb->wait());
$this->assertSame('a', $r);
}
public function testForwardsHandlersWhenFulfilledPromiseIsReturned(): void
{
$res = [];
$p = new Promise();
$p2 = new Promise();
$p2->resolve('foo');
$p2->then(function ($v) use (&$res): void {
$res[] = 'A:'.$v;
});
// $res is A:foo
$p
->then(function () use ($p2, &$res) {
$res[] = 'B';
return $p2;
})
->then(function ($v) use (&$res): void {
$res[] = 'C:'.$v;
});
$p->resolve('a');
$p->then(function ($v) use (&$res): void {
$res[] = 'D:'.$v;
});
P\Utils::queue()->run();
$this->assertSame(['A:foo', 'B', 'D:a', 'C:foo'], $res);
}
public function testForwardsHandlersWhenRejectedPromiseIsReturned(): void
{
$res = [];
$p = new Promise();
$p2 = new Promise();
$p2->reject('foo');
$p2->then(null, function ($v) use (&$res): void {
$res[] = 'A:'.$v;
});
$p->then(null, function () use ($p2, &$res) {
$res[] = 'B';
return $p2;
})
->then(null, function ($v) use (&$res): void {
$res[] = 'C:'.$v;
});
$p->reject('a');
$p->then(null, function ($v) use (&$res): void {
$res[] = 'D:'.$v;
});
P\Utils::queue()->run();
$this->assertSame(['A:foo', 'B', 'D:a', 'C:foo'], $res);
}
public function testDoesNotForwardRejectedPromise(): void
{
$res = [];
$p = new Promise();
$p2 = new Promise();
$p2->cancel();
$p2->then(function ($v) use (&$res) {
$res[] = "B:$v";
return $v;
});
$p->then(function ($v) use ($p2, &$res) {
$res[] = "B:$v";
return $p2;
})
->then(function ($v) use (&$res): void {
$res[] = 'C:'.$v;
});
$p->resolve('a');
$p->then(function ($v) use (&$res): void {
$res[] = 'D:'.$v;
});
P\Utils::queue()->run();
$this->assertSame(['B:a', 'D:a'], $res);
}
public function testRecursivelyForwardsWhenOnlyThennable(): void
{
$res = [];
$p = new Promise();
$p2 = new Thennable();
$p2->resolve('foo');
$p2->then(function ($v) use (&$res): void {
$res[] = 'A:'.$v;
});
$p->then(function () use ($p2, &$res) {
$res[] = 'B';
return $p2;
})
->then(function ($v) use (&$res): void {
$res[] = 'C:'.$v;
});
$p->resolve('a');
$p->then(function ($v) use (&$res): void {
$res[] = 'D:'.$v;
});
P\Utils::queue()->run();
$this->assertSame(['A:foo', 'B', 'D:a', 'C:foo'], $res);
}
public function testRecursivelyForwardsWhenNotInstanceOfPromise(): void
{
$res = [];
$p = new Promise();
$p2 = new NotPromiseInstance();
$p2->then(function ($v) use (&$res): void {
$res[] = 'A:'.$v;
});
$p->then(function () use ($p2, &$res) {
$res[] = 'B';
return $p2;
})
->then(function ($v) use (&$res): void {
$res[] = 'C:'.$v;
});
$p->resolve('a');
$p->then(function ($v) use (&$res): void {
$res[] = 'D:'.$v;
});
P\Utils::queue()->run();
$this->assertSame(['B', 'D:a'], $res);
$p2->resolve('foo');
P\Utils::queue()->run();
$this->assertSame(['B', 'D:a', 'A:foo', 'C:foo'], $res);
}
public function testCannotResolveWithSelf(): void
{
$this->expectException(\LogicException::class);
$this->expectExceptionMessage('Cannot fulfill or reject a promise with itself');
$p = new Promise();
$p->resolve($p);
}
public function testCannotRejectWithSelf(): void
{
$this->expectException(\LogicException::class);
$this->expectExceptionMessage('Cannot fulfill or reject a promise with itself');
$p = new Promise();
$p->reject($p);
}
public function testDoesNotBlowStackWhenWaitingOnNestedThens(): void
{
$inner = new Promise(function () use (&$inner): void {
$inner->resolve(0);
});
$prev = $inner;
for ($i = 1; $i < 100; ++$i) {
$prev = $prev->then(function ($i) {
return $i + 1;
});
}
$parent = new Promise(function () use (&$parent, $prev): void {
$parent->resolve($prev);
});
$this->assertSame(99, $parent->wait());
}
public function testOtherwiseIsSugarForRejections(): void
{
$p = new Promise();
$p->reject('foo');
$p->otherwise(function ($v) use (&$c): void {
$c = $v;
});
P\Utils::queue()->run();
$this->assertSame($c, 'foo');
}
public function testRepeatedWaitFulfilled(): void
{
$promise = new Promise(function () use (&$promise): void {
$promise->resolve('foo');
});
$this->assertSame('foo', $promise->wait());
$this->assertSame('foo', $promise->wait());
}
public function testRepeatedWaitRejected(): void
{
$promise = new Promise(function () use (&$promise): void {
$promise->reject(new \RuntimeException('foo'));
});
$exceptionCount = 0;
try {
$promise->wait();
} catch (\Exception $e) {
$this->assertSame('foo', $e->getMessage());
++$exceptionCount;
}
try {
$promise->wait();
} catch (\Exception $e) {
$this->assertSame('foo', $e->getMessage());
++$exceptionCount;
}
$this->assertSame(2, $exceptionCount);
}
}

29
vendor/guzzlehttp/promises/tests/PropertyHelper.php

@ -1,29 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Promise\Tests;
/**
* A class to help get properties of an object.
*
* @internal
*
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class PropertyHelper
{
/**
* @param object $object
* @param string $property
*
* @throws \ReflectionException
*/
public static function get($object, $property)
{
$property = (new \ReflectionObject($object))->getProperty($property);
$property->setAccessible(true);
return $property->getValue($object);
}
}

151
vendor/guzzlehttp/promises/tests/RejectedPromiseTest.php

@ -1,151 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Promise\Tests;
use GuzzleHttp\Promise as P;
use GuzzleHttp\Promise\Promise;
use GuzzleHttp\Promise\RejectedPromise;
use PHPUnit\Framework\TestCase;
/**
* @covers \GuzzleHttp\Promise\RejectedPromise
*/
class RejectedPromiseTest extends TestCase
{
public function testThrowsReasonWhenWaitedUpon(): void
{
$p = new RejectedPromise('foo');
$this->assertTrue(P\Is::rejected($p));
try {
$p->wait(true);
$this->fail();
} catch (\Exception $e) {
$this->assertTrue(P\Is::rejected($p));
$this->assertStringContainsString('foo', $e->getMessage());
}
}
public function testCannotCancel(): void
{
$p = new RejectedPromise('foo');
$p->cancel();
$this->assertTrue(P\Is::rejected($p));
}
/**
* @exepctedExceptionMessage Cannot resolve a rejected promise
*/
public function testCannotResolve(): void
{
$this->expectException(\LogicException::class);
$p = new RejectedPromise('foo');
$p->resolve('bar');
}
/**
* @expectedExceptionMessage Cannot reject a rejected promise
*/
public function testCannotReject(): void
{
$this->expectException(\LogicException::class);
$p = new RejectedPromise('foo');
$p->reject('bar');
}
public function testCanRejectWithSameValue(): void
{
$p = new RejectedPromise('foo');
$p->reject('foo');
$this->assertTrue(P\Is::rejected($p));
}
public function testThrowsSpecificException(): void
{
$e = new \Exception();
$p = new RejectedPromise($e);
try {
$p->wait(true);
$this->fail();
} catch (\Exception $e2) {
$this->assertSame($e, $e2);
}
}
public function testCannotResolveWithPromise(): void
{
$this->expectException(\InvalidArgumentException::class);
new RejectedPromise(new Promise());
}
public function testReturnsSelfWhenNoOnReject(): void
{
$p = new RejectedPromise('a');
$this->assertSame($p, $p->then());
}
public function testInvokesOnRejectedAsynchronously(): void
{
$p = new RejectedPromise('a');
$r = null;
$f = function ($reason) use (&$r): void { $r = $reason; };
$p->then(null, $f);
$this->assertNull($r);
P\Utils::queue()->run();
$this->assertSame('a', $r);
}
public function testReturnsNewRejectedWhenOnRejectedFails(): void
{
$p = new RejectedPromise('a');
$f = function (): void { throw new \Exception('b'); };
$p2 = $p->then(null, $f);
$this->assertNotSame($p, $p2);
try {
$p2->wait();
$this->fail();
} catch (\Exception $e) {
$this->assertSame('b', $e->getMessage());
}
}
public function testWaitingIsNoOp(): void
{
$p = new RejectedPromise('a');
$p->wait(false);
$this->assertTrue(P\Is::rejected($p));
}
public function testOtherwiseIsSugarForRejections(): void
{
$p = new RejectedPromise('foo');
$p->otherwise(function ($v) use (&$c): void { $c = $v; });
P\Utils::queue()->run();
$this->assertSame('foo', $c);
}
public function testCanResolveThenWithSuccess(): void
{
$actual = null;
$p = new RejectedPromise('foo');
$p->otherwise(function ($v) {
return $v.' bar';
})->then(function ($v) use (&$actual): void {
$actual = $v;
});
P\Utils::queue()->run();
$this->assertSame('foo bar', $actual);
}
public function testDoesNotTryToRejectTwiceDuringTrampoline(): void
{
$fp = new RejectedPromise('a');
$t1 = $fp->then(null, function ($v) { return $v.' b'; });
$t1->resolve('why!');
$this->assertSame('why!', $t1->wait());
}
}

30
vendor/guzzlehttp/promises/tests/RejectionExceptionTest.php

@ -1,30 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Promise\Tests;
use GuzzleHttp\Promise\RejectionException;
use PHPUnit\Framework\TestCase;
/**
* @covers \GuzzleHttp\Promise\RejectionException
*/
class RejectionExceptionTest extends TestCase
{
public function testCanGetReasonFromException(): void
{
$thing = new Thing1('foo');
$e = new RejectionException($thing);
$this->assertSame($thing, $e->getReason());
$this->assertSame('The promise was rejected with reason: foo', $e->getMessage());
}
public function testCanGetReasonMessageFromJson(): void
{
$reason = new Thing2();
$e = new RejectionException($reason);
$this->assertStringContainsString('{}', $e->getMessage());
}
}

35
vendor/guzzlehttp/promises/tests/TaskQueueTest.php

@ -1,35 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Promise\Tests;
use GuzzleHttp\Promise\TaskQueue;
use PHPUnit\Framework\TestCase;
class TaskQueueTest extends TestCase
{
public function testKnowsIfEmpty(): void
{
$tq = new TaskQueue(false);
$this->assertTrue($tq->isEmpty());
}
public function testKnowsIfFull(): void
{
$tq = new TaskQueue(false);
$tq->add(function (): void {});
$this->assertFalse($tq->isEmpty());
}
public function testExecutesTasksInOrder(): void
{
$tq = new TaskQueue(false);
$called = [];
$tq->add(function () use (&$called): void { $called[] = 'a'; });
$tq->add(function () use (&$called): void { $called[] = 'b'; });
$tq->add(function () use (&$called): void { $called[] = 'c'; });
$tq->run();
$this->assertSame(['a', 'b', 'c'], $called);
}
}

27
vendor/guzzlehttp/promises/tests/Thennable.php

@ -1,27 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Promise\Tests;
use GuzzleHttp\Promise\Promise;
class Thennable
{
private $nextPromise;
public function __construct()
{
$this->nextPromise = new Promise();
}
public function then(?callable $res = null, ?callable $rej = null)
{
return $this->nextPromise->then($res, $rej);
}
public function resolve($value): void
{
$this->nextPromise->resolve($value);
}
}

20
vendor/guzzlehttp/promises/tests/Thing1.php

@ -1,20 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Promise\Tests;
class Thing1
{
private $message;
public function __construct($message)
{
$this->message = $message;
}
public function __toString()
{
return $this->message;
}
}

14
vendor/guzzlehttp/promises/tests/Thing2.php

@ -1,14 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Promise\Tests;
class Thing2 implements \JsonSerializable
{
#[\ReturnTypeWillChange]
public function jsonSerialize()
{
return '{}';
}
}

734
vendor/guzzlehttp/promises/tests/UtilsTest.php

@ -1,734 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Promise\Tests;
use GuzzleHttp\Promise\AggregateException;
use GuzzleHttp\Promise as P;
use GuzzleHttp\Promise\FulfilledPromise;
use GuzzleHttp\Promise\Promise;
use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Promise\RejectedPromise;
use GuzzleHttp\Promise\RejectionException;
use GuzzleHttp\Promise\TaskQueue;
use PHPUnit\Framework\TestCase;
class UtilsTest extends TestCase
{
public function testWaitsOnAllPromisesIntoArray(): void
{
$e = new \Exception();
$a = new Promise(function () use (&$a): void { $a->resolve('a'); });
$b = new Promise(function () use (&$b): void { $b->reject('b'); });
$c = new Promise(function () use (&$c, $e): void { $c->reject($e); });
$results = P\Utils::inspectAll([$a, $b, $c]);
$this->assertSame([
['state' => 'fulfilled', 'value' => 'a'],
['state' => 'rejected', 'reason' => 'b'],
['state' => 'rejected', 'reason' => $e],
], $results);
}
public function testUnwrapsPromisesWithNoDefaultAndFailure(): void
{
$this->expectException(RejectionException::class);
$promises = [new FulfilledPromise('a'), new Promise()];
P\Utils::unwrap($promises);
}
public function testUnwrapsPromisesWithNoDefault(): void
{
$promises = [new FulfilledPromise('a')];
$this->assertSame(['a'], P\Utils::unwrap($promises));
}
public function testUnwrapsPromisesWithKeys(): void
{
$promises = [
'foo' => new FulfilledPromise('a'),
'bar' => new FulfilledPromise('b'),
];
$this->assertSame([
'foo' => 'a',
'bar' => 'b',
], P\Utils::unwrap($promises));
}
public function testAllAggregatesSortedArray(): void
{
$a = new Promise();
$b = new Promise();
$c = new Promise();
$d = P\Utils::all([$a, $b, $c]);
$b->resolve('b');
$a->resolve('a');
$c->resolve('c');
$d->then(
function ($value) use (&$result): void { $result = $value; },
function ($reason) use (&$result): void { $result = $reason; }
);
P\Utils::queue()->run();
$this->assertSame(['a', 'b', 'c'], $result);
}
public function testPromisesDynamicallyAddedToStack(): void
{
$promises = new \ArrayIterator();
$counter = 0;
$promises['a'] = new FulfilledPromise('a');
$promises['b'] = $promise = new Promise(function () use (&$promise, &$promises, &$counter): void {
++$counter; // Make sure the wait function is called only once
$promise->resolve('b');
$promises['c'] = $subPromise = new Promise(function () use (&$subPromise): void {
$subPromise->resolve('c');
});
});
$result = P\Utils::all($promises, true)->wait();
$this->assertCount(3, $promises);
$this->assertCount(3, $result);
$this->assertSame($result['c'], 'c');
$this->assertSame(1, $counter);
}
public function testAllThrowsWhenAnyRejected(): void
{
$a = new Promise();
$b = new Promise();
$c = new Promise();
$d = P\Utils::all([$a, $b, $c]);
$b->resolve('b');
$a->reject('fail');
$c->resolve('c');
$d->then(
function ($value) use (&$result): void { $result = $value; },
function ($reason) use (&$result): void { $result = $reason; }
);
P\Utils::queue()->run();
$this->assertSame('fail', $result);
}
public function testSomeAggregatesSortedArrayWithMax(): void
{
$a = new Promise();
$b = new Promise();
$c = new Promise();
$d = P\Utils::some(2, [$a, $b, $c]);
$b->resolve('b');
$c->resolve('c');
$a->resolve('a');
$d->then(function ($value) use (&$result): void { $result = $value; });
P\Utils::queue()->run();
$this->assertSame(['b', 'c'], $result);
}
public function testSomeRejectsWhenTooManyRejections(): void
{
$a = new Promise();
$b = new Promise();
$d = P\Utils::some(2, [$a, $b]);
$a->reject('bad');
$b->resolve('good');
P\Utils::queue()->run();
$this->assertTrue(P\Is::rejected($d));
$d->then(null, function ($reason) use (&$called): void {
$called = $reason;
});
P\Utils::queue()->run();
$this->assertInstanceOf(AggregateException::class, $called);
$this->assertContains('bad', $called->getReason());
}
public function testCanWaitUntilSomeCountIsSatisfied(): void
{
$a = new Promise(function () use (&$a): void { $a->resolve('a'); });
$b = new Promise(function () use (&$b): void { $b->resolve('b'); });
$c = new Promise(function () use (&$c): void { $c->resolve('c'); });
$d = P\Utils::some(2, [$a, $b, $c]);
$this->assertSame(['a', 'b'], $d->wait());
}
public function testThrowsIfImpossibleToWaitForSomeCount(): void
{
$this->expectException(AggregateException::class);
$this->expectExceptionMessage('Not enough promises to fulfill count');
$a = new Promise(function () use (&$a): void { $a->resolve('a'); });
$d = P\Utils::some(2, [$a]);
$d->wait();
}
public function testThrowsIfResolvedWithoutCountTotalResults(): void
{
$this->expectException(AggregateException::class);
$this->expectExceptionMessage('Not enough promises to fulfill count');
$a = new Promise();
$b = new Promise();
$d = P\Utils::some(3, [$a, $b]);
$a->resolve('a');
$b->resolve('b');
$d->wait();
}
public function testAnyReturnsFirstMatch(): void
{
$a = new Promise();
$b = new Promise();
$c = P\Utils::any([$a, $b]);
$b->resolve('b');
$a->resolve('a');
$c->then(function ($value) use (&$result): void { $result = $value; });
P\Utils::queue()->run();
$this->assertSame('b', $result);
}
public function testSettleFulfillsWithFulfilledAndRejected(): void
{
$a = new Promise();
$b = new Promise();
$c = new Promise();
$d = P\Utils::settle([$a, $b, $c]);
$b->resolve('b');
$c->resolve('c');
$a->reject('a');
P\Utils::queue()->run();
$this->assertTrue(P\Is::fulfilled($d));
$d->then(function ($value) use (&$result): void { $result = $value; });
P\Utils::queue()->run();
$this->assertSame([
['state' => 'rejected', 'reason' => 'a'],
['state' => 'fulfilled', 'value' => 'b'],
['state' => 'fulfilled', 'value' => 'c'],
], $result);
}
public function testCanInspectFulfilledPromise(): void
{
$p = new FulfilledPromise('foo');
$this->assertSame([
'state' => 'fulfilled',
'value' => 'foo',
], P\Utils::inspect($p));
}
public function testCanInspectRejectedPromise(): void
{
$p = new RejectedPromise('foo');
$this->assertSame([
'state' => 'rejected',
'reason' => 'foo',
], P\Utils::inspect($p));
}
public function testCanInspectRejectedPromiseWithNormalException(): void
{
$e = new \Exception('foo');
$p = new RejectedPromise($e);
$this->assertSame([
'state' => 'rejected',
'reason' => $e,
], P\Utils::inspect($p));
}
public function testReturnsTrampoline(): void
{
$this->assertInstanceOf(TaskQueue::class, P\Utils::queue());
$this->assertSame(P\Utils::queue(), P\Utils::queue());
}
public function testCanScheduleThunk(): void
{
$tramp = P\Utils::queue();
$promise = P\Utils::task(function () { return 'Hi!'; });
$c = null;
$promise->then(function ($v) use (&$c): void { $c = $v; });
$this->assertNull($c);
$tramp->run();
$this->assertSame('Hi!', $c);
}
public function testCanScheduleThunkWithRejection(): void
{
$tramp = P\Utils::queue();
$promise = P\Utils::task(function (): void { throw new \Exception('Hi!'); });
$c = null;
$promise->otherwise(function ($v) use (&$c): void { $c = $v; });
$this->assertNull($c);
$tramp->run();
$this->assertSame('Hi!', $c->getMessage());
}
public function testCanScheduleThunkWithWait(): void
{
$tramp = P\Utils::queue();
$promise = P\Utils::task(function () { return 'a'; });
$this->assertSame('a', $promise->wait());
$tramp->run();
}
public function testYieldsFromCoroutine(): void
{
if (defined('HHVM_VERSION')) {
$this->markTestIncomplete('Broken on HHVM.');
}
$promise = P\Coroutine::of(function () {
$value = (yield new FulfilledPromise('a'));
yield $value.'b';
});
$promise->then(function ($value) use (&$result): void { $result = $value; });
P\Utils::queue()->run();
$this->assertSame('ab', $result);
}
public function testCanCatchExceptionsInCoroutine(): void
{
if (defined('HHVM_VERSION')) {
$this->markTestIncomplete('Broken on HHVM.');
}
$promise = P\Coroutine::of(function () {
try {
yield new RejectedPromise('a');
$this->fail('Should have thrown into the coroutine!');
} catch (RejectionException $e) {
$value = (yield new FulfilledPromise($e->getReason()));
yield $value.'b';
}
});
$promise->then(function ($value) use (&$result): void { $result = $value; });
P\Utils::queue()->run();
$this->assertTrue(P\Is::fulfilled($promise));
$this->assertSame('ab', $result);
}
/**
* @dataProvider rejectsParentExceptionProvider
*/
public function testRejectsParentExceptionWhenException(PromiseInterface $promise): void
{
$promise->then(
function (): void { $this->fail(); },
function ($reason) use (&$result): void { $result = $reason; }
);
P\Utils::queue()->run();
$this->assertInstanceOf(\Exception::class, $result);
$this->assertSame('a', $result->getMessage());
}
public function rejectsParentExceptionProvider()
{
return [
[P\Coroutine::of(function () {
yield new FulfilledPromise(0);
throw new \Exception('a');
})],
[P\Coroutine::of(function () {
throw new \Exception('a');
yield new FulfilledPromise(0);
})],
];
}
public function testCanRejectFromRejectionCallback(): void
{
if (defined('HHVM_VERSION')) {
$this->markTestIncomplete('Broken on HHVM.');
}
$promise = P\Coroutine::of(function () {
yield new FulfilledPromise(0);
yield new RejectedPromise('no!');
});
$promise->then(
function (): void { $this->fail(); },
function ($reason) use (&$result): void { $result = $reason; }
);
P\Utils::queue()->run();
$this->assertInstanceOf(RejectionException::class, $result);
$this->assertSame('no!', $result->getReason());
}
public function testCanAsyncReject(): void
{
if (defined('HHVM_VERSION')) {
$this->markTestIncomplete('Broken on HHVM.');
}
$rej = new Promise();
$promise = P\Coroutine::of(function () use ($rej) {
yield new FulfilledPromise(0);
yield $rej;
});
$promise->then(
function (): void { $this->fail(); },
function ($reason) use (&$result): void { $result = $reason; }
);
$rej->reject('no!');
P\Utils::queue()->run();
$this->assertInstanceOf(RejectionException::class, $result);
$this->assertSame('no!', $result->getReason());
}
public function testCanCatchAndThrowOtherException(): void
{
$promise = P\Coroutine::of(function () {
try {
yield new RejectedPromise('a');
$this->fail('Should have thrown into the coroutine!');
} catch (RejectionException $e) {
throw new \Exception('foo');
}
});
$promise->otherwise(function ($value) use (&$result): void { $result = $value; });
P\Utils::queue()->run();
$this->assertTrue(P\Is::rejected($promise));
$this->assertStringContainsString('foo', $result->getMessage());
}
public function testCanCatchAndYieldOtherException(): void
{
if (defined('HHVM_VERSION')) {
$this->markTestIncomplete('Broken on HHVM.');
}
$promise = P\Coroutine::of(function () {
try {
yield new RejectedPromise('a');
$this->fail('Should have thrown into the coroutine!');
} catch (RejectionException $e) {
yield new RejectedPromise('foo');
}
});
$promise->otherwise(function ($value) use (&$result): void { $result = $value; });
P\Utils::queue()->run();
$this->assertTrue(P\Is::rejected($promise));
$this->assertStringContainsString('foo', $result->getMessage());
}
public function createLotsOfSynchronousPromise()
{
return P\Coroutine::of(function () {
$value = 0;
for ($i = 0; $i < 1000; ++$i) {
$value = (yield new FulfilledPromise($i));
}
yield $value;
});
}
public function testLotsOfSynchronousDoesNotBlowStack(): void
{
if (defined('HHVM_VERSION')) {
$this->markTestIncomplete('Broken on HHVM.');
}
$promise = $this->createLotsOfSynchronousPromise();
$promise->then(function ($v) use (&$r): void { $r = $v; });
P\Utils::queue()->run();
$this->assertSame(999, $r);
}
public function testLotsOfSynchronousWaitDoesNotBlowStack(): void
{
if (defined('HHVM_VERSION')) {
$this->markTestIncomplete('Broken on HHVM.');
}
$promise = $this->createLotsOfSynchronousPromise();
$promise->then(function ($v) use (&$r): void { $r = $v; });
$this->assertSame(999, $promise->wait());
$this->assertSame(999, $r);
}
private function createLotsOfFlappingPromise()
{
return P\Coroutine::of(function () {
$value = 0;
for ($i = 0; $i < 1000; ++$i) {
try {
if ($i % 2) {
$value = (yield new FulfilledPromise($i));
} else {
$value = (yield new RejectedPromise($i));
}
} catch (\Exception $e) {
$value = (yield new FulfilledPromise($i));
}
}
yield $value;
});
}
public function testLotsOfTryCatchingDoesNotBlowStack(): void
{
if (defined('HHVM_VERSION')) {
$this->markTestIncomplete('Broken on HHVM.');
}
$promise = $this->createLotsOfFlappingPromise();
$promise->then(function ($v) use (&$r): void { $r = $v; });
P\Utils::queue()->run();
$this->assertSame(999, $r);
}
public function testLotsOfTryCatchingWaitingDoesNotBlowStack(): void
{
if (defined('HHVM_VERSION')) {
$this->markTestIncomplete('Broken on HHVM.');
}
$promise = $this->createLotsOfFlappingPromise();
$promise->then(function ($v) use (&$r): void { $r = $v; });
$this->assertSame(999, $promise->wait());
$this->assertSame(999, $r);
}
public function testAsyncPromisesWithCorrectlyYieldedValues(): void
{
if (defined('HHVM_VERSION')) {
$this->markTestIncomplete('Broken on HHVM.');
}
$promises = [
new Promise(),
new Promise(),
new Promise(),
];
eval('
$promise = \GuzzleHttp\Promise\Coroutine::of(function () use ($promises) {
$value = null;
$this->assertSame(\'skip\', (yield new \GuzzleHttp\Promise\FulfilledPromise(\'skip\')));
foreach ($promises as $idx => $p) {
$value = (yield $p);
$this->assertSame($idx, $value);
$this->assertSame(\'skip\', (yield new \GuzzleHttp\Promise\FulfilledPromise(\'skip\')));
}
$this->assertSame(\'skip\', (yield new \GuzzleHttp\Promise\FulfilledPromise(\'skip\')));
yield $value;
});
');
$promises[0]->resolve(0);
$promises[1]->resolve(1);
$promises[2]->resolve(2);
$promise->then(function ($v) use (&$r): void { $r = $v; });
P\Utils::queue()->run();
$this->assertSame(2, $r);
}
public function testYieldFinalWaitablePromise(): void
{
if (defined('HHVM_VERSION')) {
$this->markTestIncomplete('Broken on HHVM.');
}
$p1 = new Promise(function () use (&$p1): void {
$p1->resolve('skip me');
});
$p2 = new Promise(function () use (&$p2): void {
$p2->resolve('hello!');
});
$co = P\Coroutine::of(function () use ($p1, $p2) {
yield $p1;
yield $p2;
});
P\Utils::queue()->run();
$this->assertSame('hello!', $co->wait());
}
public function testCanYieldFinalPendingPromise(): void
{
if (defined('HHVM_VERSION')) {
$this->markTestIncomplete('Broken on HHVM.');
}
$p1 = new Promise();
$p2 = new Promise();
$co = P\Coroutine::of(function () use ($p1, $p2) {
yield $p1;
yield $p2;
});
$p1->resolve('a');
$p2->resolve('b');
$co->then(function ($value) use (&$result): void { $result = $value; });
P\Utils::queue()->run();
$this->assertSame('b', $result);
}
public function testCanNestYieldsAndFailures(): void
{
if (defined('HHVM_VERSION')) {
$this->markTestIncomplete('Broken on HHVM.');
}
$p1 = new Promise();
$p2 = new Promise();
$p3 = new Promise();
$p4 = new Promise();
$p5 = new Promise();
$co = P\Coroutine::of(function () use ($p1, $p2, $p3, $p4, $p5) {
try {
yield $p1;
} catch (\Exception $e) {
yield $p2;
try {
yield $p3;
yield $p4;
} catch (\Exception $e) {
yield $p5;
}
}
});
$p1->reject('a');
$p2->resolve('b');
$p3->resolve('c');
$p4->reject('d');
$p5->resolve('e');
$co->then(function ($value) use (&$result): void { $result = $value; });
P\Utils::queue()->run();
$this->assertSame('e', $result);
}
public function testCanYieldErrorsAndSuccessesWithoutRecursion(): void
{
if (defined('HHVM_VERSION')) {
$this->markTestIncomplete('Broken on HHVM.');
}
$promises = [];
for ($i = 0; $i < 20; ++$i) {
$promises[] = new Promise();
}
$co = P\Coroutine::of(function () use ($promises) {
for ($i = 0; $i < 20; $i += 4) {
try {
yield $promises[$i];
yield $promises[$i + 1];
} catch (\Exception $e) {
yield $promises[$i + 2];
yield $promises[$i + 3];
}
}
});
for ($i = 0; $i < 20; $i += 4) {
$promises[$i]->resolve($i);
$promises[$i + 1]->reject($i + 1);
$promises[$i + 2]->resolve($i + 2);
$promises[$i + 3]->resolve($i + 3);
}
$co->then(function ($value) use (&$result): void { $result = $value; });
P\Utils::queue()->run();
$this->assertSame(19, $result);
}
public function testCanWaitOnPromiseAfterFulfilled(): void
{
if (defined('HHVM_VERSION')) {
$this->markTestIncomplete('Broken on HHVM.');
}
$f = function () {
static $i = 0;
++$i;
return $p = new Promise(function () use (&$p, $i): void {
$p->resolve($i.'-bar');
});
};
$promises = [];
for ($i = 0; $i < 20; ++$i) {
$promises[] = $f();
}
$p = P\Coroutine::of(function () use ($promises) {
yield new FulfilledPromise('foo!');
foreach ($promises as $promise) {
yield $promise;
}
});
$this->assertSame('20-bar', $p->wait());
}
public function testCanWaitOnErroredPromises(): void
{
if (defined('HHVM_VERSION')) {
$this->markTestIncomplete('Broken on HHVM.');
}
$p1 = new Promise(function () use (&$p1): void { $p1->reject('a'); });
$p2 = new Promise(function () use (&$p2): void { $p2->resolve('b'); });
$p3 = new Promise(function () use (&$p3): void { $p3->resolve('c'); });
$p4 = new Promise(function () use (&$p4): void { $p4->reject('d'); });
$p5 = new Promise(function () use (&$p5): void { $p5->resolve('e'); });
$p6 = new Promise(function () use (&$p6): void { $p6->reject('f'); });
$co = P\Coroutine::of(function () use ($p1, $p2, $p3, $p4, $p5, $p6) {
try {
yield $p1;
} catch (\Exception $e) {
yield $p2;
try {
yield $p3;
yield $p4;
} catch (\Exception $e) {
yield $p5;
yield $p6;
}
}
});
$res = P\Utils::inspect($co);
$this->assertSame('f', $res['reason']);
}
public function testCoroutineOtherwiseIntegrationTest(): void
{
if (defined('HHVM_VERSION')) {
$this->markTestIncomplete('Broken on HHVM.');
}
$a = new Promise();
$b = new Promise();
$promise = P\Coroutine::of(function () use ($a, $b) {
// Execute the pool of commands concurrently, and process errors.
yield $a;
yield $b;
})->otherwise(function (\Exception $e): void {
// Throw errors from the operations as a specific Multipart error.
throw new \OutOfBoundsException('a', 0, $e);
});
$a->resolve('a');
$b->reject('b');
$reason = P\Utils::inspect($promise)['reason'];
$this->assertInstanceOf(\OutOfBoundsException::class, $reason);
$this->assertInstanceOf(RejectionException::class, $reason->getPrevious());
}
public function testCanManuallySettleTaskQueueGeneratedPromises(): void
{
$p1 = P\Utils::task(function () { return 'a'; });
$p2 = P\Utils::task(function () { return 'b'; });
$p3 = P\Utils::task(function () { return 'c'; });
$p1->cancel();
$p2->resolve('b2');
$results = P\Utils::inspectAll([$p1, $p2, $p3]);
$this->assertSame([
['state' => 'rejected', 'reason' => 'Promise has been cancelled'],
['state' => 'fulfilled', 'value' => 'b2'],
['state' => 'fulfilled', 'value' => 'c'],
], $results);
}
}

9
vendor/guzzlehttp/promises/vendor-bin/php-cs-fixer/composer.json

@ -1,9 +0,0 @@
{
"require": {
"php": "^7.4 || ^8.0",
"friendsofphp/php-cs-fixer": "3.68.5"
},
"config": {
"preferred-install": "dist"
}
}

10
vendor/guzzlehttp/promises/vendor-bin/phpstan/composer.json

@ -1,10 +0,0 @@
{
"require": {
"php": "^7.4 || ^8.0",
"phpstan/phpstan": "2.1.2",
"phpstan/phpstan-deprecation-rules": "2.0.1"
},
"config": {
"preferred-install": "dist"
}
}

9
vendor/guzzlehttp/promises/vendor-bin/psalm/composer.json

@ -1,9 +0,0 @@
{
"require": {
"php": "^7.4 || ^8.0",
"psalm/phar": "5.26.1"
},
"config": {
"preferred-install": "dist"
}
}

12
vendor/guzzlehttp/psr7/.editorconfig

@ -1,12 +0,0 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[{Makefile, *.mk}]
indent_style = tab

13
vendor/guzzlehttp/psr7/.gitattributes

@ -1,13 +0,0 @@
.editorconfig export-ignore
.gitattributes export-ignore
/.github/ export-ignore
.gitignore export-ignore
.php-cs-fixer.dist.php export-ignore
/Makefile export-ignore
/phpstan-baseline.neon export-ignore
/phpstan.neon.dist export-ignore
/phpunit.xml.dist export-ignore
/psalm-baseline.xml export-ignore
/psalm.xml export-ignore
/tests/ export-ignore
/vendor-bin/ export-ignore

2
vendor/guzzlehttp/psr7/.github/.editorconfig

@ -1,2 +0,0 @@
[*.yml]
indent_size = 2

2
vendor/guzzlehttp/psr7/.github/FUNDING.yml

@ -1,2 +0,0 @@
github: [Nyholm, GrahamCampbell]
tidelift: "packagist/guzzlehttp/psr7"

14
vendor/guzzlehttp/psr7/.github/stale.yml

@ -1,14 +0,0 @@
daysUntilStale: 120
daysUntilClose: 14
exemptLabels:
- lifecycle/keep-open
- lifecycle/ready-for-merge
# Label to use when marking an issue as stale
staleLabel: lifecycle/stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed after 2 weeks if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

21
vendor/guzzlehttp/psr7/.github/workflows/checks.yml

@ -1,21 +0,0 @@
name: Checks
on:
push:
branches:
pull_request:
permissions:
contents: read
jobs:
composer-normalize:
name: Composer Normalize
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Composer normalize
uses: docker://ergebnis/composer-normalize-action

58
vendor/guzzlehttp/psr7/.github/workflows/ci.yml

@ -1,58 +0,0 @@
name: CI
on:
push:
branches:
pull_request:
permissions:
contents: read
jobs:
build-lowest-version:
name: Build lowest version
runs-on: ubuntu-22.04
steps:
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: '7.2'
ini-values: error_reporting=E_ALL
coverage: 'none'
extensions: mbstring
- name: Checkout code
uses: actions/checkout@v4
- name: Install dependencies
run: composer update --no-interaction --prefer-stable --prefer-lowest --no-progress
- name: Run tests
run: vendor/bin/phpunit --testsuite "Guzzle PSR-7 Unit Test Suite"
build:
name: Build
runs-on: ubuntu-22.04
strategy:
max-parallel: 10
matrix:
php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4']
steps:
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
ini-values: error_reporting=E_ALL
coverage: 'none'
extensions: mbstring
- name: Checkout code
uses: actions/checkout@v4
- name: Install dependencies
run: composer update --no-interaction --no-progress
- name: Run tests
run: vendor/bin/phpunit --testsuite "Guzzle PSR-7 Unit Test Suite"

45
vendor/guzzlehttp/psr7/.github/workflows/integration.yml

@ -1,45 +0,0 @@
name: Integration
on:
push:
branches:
pull_request:
permissions:
contents: read
jobs:
build:
name: Test
runs-on: ubuntu-22.04
strategy:
max-parallel: 10
matrix:
php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4']
steps:
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
ini-values: error_reporting=E_ALL
coverage: none
- name: Checkout code
uses: actions/checkout@v4
- name: Install dependencies
run: composer update --no-interaction --no-progress
- name: Start server
run: php -S 127.0.0.1:10002 tests/Integration/server.php &
- name: Run Guzzle tests
env:
TEST_SERVER: 127.0.0.1:10002
run: vendor/bin/phpunit --testsuite "Guzzle PSR-7 Integration Test Suite"
- name: Run Interop tests
env:
TEST_SERVER: 127.0.0.1:10002
run: vendor/bin/phpunit --testsuite "PSR-17 Integration Test Suite"

82
vendor/guzzlehttp/psr7/.github/workflows/static.yml

@ -1,82 +0,0 @@
name: Static analysis
on:
push:
branches:
pull_request:
permissions:
contents: read
jobs:
phpstan:
name: PHPStan
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '7.4'
coverage: none
extensions: mbstring
- name: Download dependencies
run: composer update --no-interaction --no-progress
- name: Download PHPStan
run: composer bin phpstan update --no-interaction --no-progress
- name: Execute PHPStan
run: vendor/bin/phpstan analyze --no-progress
php-cs-fixer:
name: PHP-CS-Fixer
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '7.4'
coverage: none
extensions: mbstring
- name: Download dependencies
run: composer update --no-interaction --no-progress
- name: Download PHP CS Fixer
run: composer bin php-cs-fixer update --no-interaction --no-progress
- name: Execute PHP CS Fixer
run: vendor/bin/php-cs-fixer fix --diff --dry-run
psalm:
name: Psalm
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '7.4'
coverage: none
extensions: mbstring
- name: Download dependencies
run: composer update --no-interaction --no-progress
- name: Download Psalm
run: composer bin psalm update --no-interaction --no-progress
- name: Execute Psalm
run: vendor/bin/psalm.phar --no-progress --output-format=github

7
vendor/guzzlehttp/psr7/.gitignore

@ -1,7 +0,0 @@
.php-cs-fixer.php
.php-cs-fixer.cache
.phpunit.result.cache
composer.lock
vendor/
/phpstan.neon
/phpunit.xml

28
vendor/guzzlehttp/psr7/.php-cs-fixer.dist.php

@ -1,28 +0,0 @@
<?php
$config = (new PhpCsFixer\Config())
->setRiskyAllowed(true)
->setRules([
'@PHP71Migration:risky' => true,
'@PHPUnit75Migration:risky' => true,
'@PSR12:risky' => true,
'@Symfony' => true,
'global_namespace_import' => false,
'no_superfluous_phpdoc_tags' => [
'allow_mixed' => true,
],
'phpdoc_annotation_without_dot' => false,
'phpdoc_summary' => false,
'phpdoc_to_comment' => false,
'single_line_throw' => false,
'yoda_style' => false,
])
->setFinder(
PhpCsFixer\Finder::create()
->in(__DIR__.'/src')
->in(__DIR__.'/tests')
->name('*.php')
)
;
return $config;

18
vendor/guzzlehttp/psr7/Makefile

@ -1,18 +0,0 @@
test:
vendor/bin/phpunit $(TEST)
check-tag:
$(if $(TAG),,$(error TAG is not defined. Pass via "make tag TAG=4.2.1"))
tag: check-tag
@echo Tagging $(TAG)
chag update $(TAG)
git commit -a -m '$(TAG) release'
chag tag
@echo "Release has been created. Push using 'make release'"
@echo "Changes made in the release commit"
git diff HEAD~1 HEAD
release: check-tag
git push origin master
git push origin $(TAG)

751
vendor/guzzlehttp/psr7/phpstan-baseline.neon

@ -1,751 +0,0 @@
parameters:
ignoreErrors:
-
message: '#^Unreachable statement \- code above always terminates\.$#'
identifier: deadCode.unreachable
count: 1
path: src/AppendStream.php
-
message: '#^Method GuzzleHttp\\Psr7\\BufferStream\:\:getSize\(\) never returns null so it can be removed from the return type\.$#'
identifier: return.unusedType
count: 1
path: src/BufferStream.php
-
message: '#^Unreachable statement \- code above always terminates\.$#'
identifier: deadCode.unreachable
count: 1
path: src/CachingStream.php
-
message: '#^Unreachable statement \- code above always terminates\.$#'
identifier: deadCode.unreachable
count: 1
path: src/DroppingStream.php
-
message: '#^Access to an undefined property GuzzleHttp\\Psr7\\FnStream\:\:\$_fn___toString\.$#'
identifier: property.notFound
count: 1
path: src/FnStream.php
-
message: '#^Access to an undefined property GuzzleHttp\\Psr7\\FnStream\:\:\$_fn_close\.$#'
identifier: property.notFound
count: 1
path: src/FnStream.php
-
message: '#^Access to an undefined property GuzzleHttp\\Psr7\\FnStream\:\:\$_fn_detach\.$#'
identifier: property.notFound
count: 1
path: src/FnStream.php
-
message: '#^Access to an undefined property GuzzleHttp\\Psr7\\FnStream\:\:\$_fn_eof\.$#'
identifier: property.notFound
count: 1
path: src/FnStream.php
-
message: '#^Access to an undefined property GuzzleHttp\\Psr7\\FnStream\:\:\$_fn_getContents\.$#'
identifier: property.notFound
count: 1
path: src/FnStream.php
-
message: '#^Access to an undefined property GuzzleHttp\\Psr7\\FnStream\:\:\$_fn_getMetadata\.$#'
identifier: property.notFound
count: 1
path: src/FnStream.php
-
message: '#^Access to an undefined property GuzzleHttp\\Psr7\\FnStream\:\:\$_fn_getSize\.$#'
identifier: property.notFound
count: 1
path: src/FnStream.php
-
message: '#^Access to an undefined property GuzzleHttp\\Psr7\\FnStream\:\:\$_fn_isReadable\.$#'
identifier: property.notFound
count: 1
path: src/FnStream.php
-
message: '#^Access to an undefined property GuzzleHttp\\Psr7\\FnStream\:\:\$_fn_isSeekable\.$#'
identifier: property.notFound
count: 1
path: src/FnStream.php
-
message: '#^Access to an undefined property GuzzleHttp\\Psr7\\FnStream\:\:\$_fn_isWritable\.$#'
identifier: property.notFound
count: 1
path: src/FnStream.php
-
message: '#^Access to an undefined property GuzzleHttp\\Psr7\\FnStream\:\:\$_fn_read\.$#'
identifier: property.notFound
count: 1
path: src/FnStream.php
-
message: '#^Access to an undefined property GuzzleHttp\\Psr7\\FnStream\:\:\$_fn_rewind\.$#'
identifier: property.notFound
count: 1
path: src/FnStream.php
-
message: '#^Access to an undefined property GuzzleHttp\\Psr7\\FnStream\:\:\$_fn_seek\.$#'
identifier: property.notFound
count: 1
path: src/FnStream.php
-
message: '#^Access to an undefined property GuzzleHttp\\Psr7\\FnStream\:\:\$_fn_tell\.$#'
identifier: property.notFound
count: 1
path: src/FnStream.php
-
message: '#^Access to an undefined property GuzzleHttp\\Psr7\\FnStream\:\:\$_fn_write\.$#'
identifier: property.notFound
count: 1
path: src/FnStream.php
-
message: '#^Method GuzzleHttp\\Psr7\\FnStream\:\:detach\(\) should return resource\|null but returns mixed\.$#'
identifier: return.type
count: 1
path: src/FnStream.php
-
message: '#^Method GuzzleHttp\\Psr7\\FnStream\:\:eof\(\) should return bool but returns mixed\.$#'
identifier: return.type
count: 1
path: src/FnStream.php
-
message: '#^Method GuzzleHttp\\Psr7\\FnStream\:\:getContents\(\) should return string but returns mixed\.$#'
identifier: return.type
count: 1
path: src/FnStream.php
-
message: '#^Method GuzzleHttp\\Psr7\\FnStream\:\:getSize\(\) should return int\|null but returns mixed\.$#'
identifier: return.type
count: 1
path: src/FnStream.php
-
message: '#^Method GuzzleHttp\\Psr7\\FnStream\:\:isReadable\(\) should return bool but returns mixed\.$#'
identifier: return.type
count: 1
path: src/FnStream.php
-
message: '#^Method GuzzleHttp\\Psr7\\FnStream\:\:isSeekable\(\) should return bool but returns mixed\.$#'
identifier: return.type
count: 1
path: src/FnStream.php
-
message: '#^Method GuzzleHttp\\Psr7\\FnStream\:\:isWritable\(\) should return bool but returns mixed\.$#'
identifier: return.type
count: 1
path: src/FnStream.php
-
message: '#^Method GuzzleHttp\\Psr7\\FnStream\:\:read\(\) should return string but returns mixed\.$#'
identifier: return.type
count: 1
path: src/FnStream.php
-
message: '#^Method GuzzleHttp\\Psr7\\FnStream\:\:tell\(\) should return int but returns mixed\.$#'
identifier: return.type
count: 1
path: src/FnStream.php
-
message: '#^Method GuzzleHttp\\Psr7\\FnStream\:\:write\(\) should return int but returns mixed\.$#'
identifier: return.type
count: 1
path: src/FnStream.php
-
message: '#^Trying to invoke mixed but it''s not a callable\.$#'
identifier: callable.nonCallable
count: 16
path: src/FnStream.php
-
message: '#^Unreachable statement \- code above always terminates\.$#'
identifier: deadCode.unreachable
count: 1
path: src/FnStream.php
-
message: '#^Call to function is_string\(\) with string will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: src/Header.php
-
message: '#^Parameter \#1 \$values of static method GuzzleHttp\\Psr7\\Header\:\:splitList\(\) expects array\<string\>\|string, mixed given\.$#'
identifier: argument.type
count: 2
path: src/Header.php
-
message: '#^Parameter \#2 \$character_mask of function trim expects string, mixed given\.$#'
identifier: argument.type
count: 3
path: src/Header.php
-
message: '#^Parameter \#1 \$method of class GuzzleHttp\\Psr7\\ServerRequest constructor expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/HttpFactory.php
-
message: '#^Unreachable statement \- code above always terminates\.$#'
identifier: deadCode.unreachable
count: 1
path: src/InflateStream.php
-
message: '#^Unreachable statement \- code above always terminates\.$#'
identifier: deadCode.unreachable
count: 1
path: src/LazyOpenStream.php
-
message: '#^Unreachable statement \- code above always terminates\.$#'
identifier: deadCode.unreachable
count: 1
path: src/LimitStream.php
-
message: '#^Binary operation "\." between ''Invalid response…'' and mixed results in an error\.$#'
identifier: binaryOp.invalid
count: 1
path: src/Message.php
-
message: '#^Binary operation "\." between ''http\://''\|''https\://'' and mixed results in an error\.$#'
identifier: binaryOp.invalid
count: 1
path: src/Message.php
-
message: '#^Cannot access offset 0 on mixed\.$#'
identifier: offsetAccess.nonOffsetAccessible
count: 1
path: src/Message.php
-
message: '#^PHPDoc tag @var with type array\<array\> is not subtype of native type list\<array\<string\>\>\.$#'
identifier: varTag.nativeType
count: 1
path: src/Message.php
-
message: '#^Parameter \#1 \$haystack of function substr_count expects string, string\|null given\.$#'
identifier: argument.type
count: 1
path: src/Message.php
-
message: '#^Parameter \#1 \$string of function substr expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Message.php
-
message: '#^Parameter \#2 \$headers of class GuzzleHttp\\Psr7\\Response constructor expects array\<array\<string\>\|string\>, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Message.php
-
message: '#^Parameter \#2 \$headers of static method GuzzleHttp\\Psr7\\Message\:\:parseRequestUri\(\) expects array, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Message.php
-
message: '#^Parameter \#2 \$str of function explode expects string, mixed given\.$#'
identifier: argument.type
count: 2
path: src/Message.php
-
message: '#^Parameter \#2 \$subject of function preg_match expects string, mixed given\.$#'
identifier: argument.type
count: 2
path: src/Message.php
-
message: '#^Parameter \#2 \$subject of function preg_match expects string, string\|null given\.$#'
identifier: argument.type
count: 1
path: src/Message.php
-
message: '#^Parameter \#2 \$subject of function preg_match_all expects string, string\|null given\.$#'
identifier: argument.type
count: 1
path: src/Message.php
-
message: '#^Parameter \#3 \$body of class GuzzleHttp\\Psr7\\Response constructor expects Psr\\Http\\Message\\StreamInterface\|resource\|string\|null, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Message.php
-
message: '#^Parameter \#3 \$headers of class GuzzleHttp\\Psr7\\Request constructor expects array\<array\<string\>\|string\>, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Message.php
-
message: '#^Parameter \#4 \$body of class GuzzleHttp\\Psr7\\Request constructor expects Psr\\Http\\Message\\StreamInterface\|resource\|string\|null, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Message.php
-
message: '#^Variable \$headerLines in PHPDoc tag @var does not match assigned variable \$count\.$#'
identifier: varTag.differentVariable
count: 1
path: src/Message.php
-
message: '#^Parameter \#1 \$name of method GuzzleHttp\\Psr7\\MultipartStream\:\:createElement\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/MultipartStream.php
-
message: '#^Parameter \#1 \$resource of static method GuzzleHttp\\Psr7\\Utils\:\:streamFor\(\) expects bool\|\(callable\(\)\: mixed\)\|float\|int\|Iterator\|Psr\\Http\\Message\\StreamInterface\|resource\|string\|null, mixed given\.$#'
identifier: argument.type
count: 1
path: src/MultipartStream.php
-
message: '#^Parameter \#3 \$filename of method GuzzleHttp\\Psr7\\MultipartStream\:\:createElement\(\) expects string\|null, mixed given\.$#'
identifier: argument.type
count: 1
path: src/MultipartStream.php
-
message: '#^Parameter \#4 \$headers of method GuzzleHttp\\Psr7\\MultipartStream\:\:createElement\(\) expects array\<string\>, mixed given\.$#'
identifier: argument.type
count: 1
path: src/MultipartStream.php
-
message: '#^Unreachable statement \- code above always terminates\.$#'
identifier: deadCode.unreachable
count: 1
path: src/MultipartStream.php
-
message: '#^Unreachable statement \- code above always terminates\.$#'
identifier: deadCode.unreachable
count: 1
path: src/NoSeekStream.php
-
message: '#^Unreachable statement \- code above always terminates\.$#'
identifier: deadCode.unreachable
count: 1
path: src/PumpStream.php
-
message: '#^Cannot cast mixed to int\.$#'
identifier: cast.int
count: 1
path: src/Query.php
-
message: '#^Cannot cast mixed to string\.$#'
identifier: cast.string
count: 3
path: src/Query.php
-
message: '#^Cannot access offset int\|string on mixed\.$#'
identifier: offsetAccess.nonOffsetAccessible
count: 5
path: src/ServerRequest.php
-
message: '#^Cannot cast mixed to int\.$#'
identifier: cast.int
count: 2
path: src/ServerRequest.php
-
message: '#^Method GuzzleHttp\\Psr7\\ServerRequest\:\:normalizeNestedFileSpec\(\) should return array\<Psr\\Http\\Message\\UploadedFileInterface\> but returns array\<int\|string, array\<Psr\\Http\\Message\\UploadedFileInterface\>\|Psr\\Http\\Message\\UploadedFileInterface\>\.$#'
identifier: return.type
count: 1
path: src/ServerRequest.php
-
message: '#^Parameter \#1 \$authority of static method GuzzleHttp\\Psr7\\ServerRequest\:\:extractHostAndPortFromAuthority\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/ServerRequest.php
-
message: '#^Parameter \#1 \$host of method GuzzleHttp\\Psr7\\Uri\:\:withHost\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 3
path: src/ServerRequest.php
-
message: '#^Parameter \#1 \$input of function array_keys expects array, mixed given\.$#'
identifier: argument.type
count: 1
path: src/ServerRequest.php
-
message: '#^Parameter \#1 \$method of class GuzzleHttp\\Psr7\\ServerRequest constructor expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/ServerRequest.php
-
message: '#^Parameter \#1 \$port of method GuzzleHttp\\Psr7\\Uri\:\:withPort\(\) expects int\|null, mixed given\.$#'
identifier: argument.type
count: 2
path: src/ServerRequest.php
-
message: '#^Parameter \#1 \$query of method GuzzleHttp\\Psr7\\Uri\:\:withQuery\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/ServerRequest.php
-
message: '#^Parameter \#1 \$streamOrFile of class GuzzleHttp\\Psr7\\UploadedFile constructor expects Psr\\Http\\Message\\StreamInterface\|resource\|string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/ServerRequest.php
-
message: '#^Parameter \#2 \$str of function explode expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/ServerRequest.php
-
message: '#^Parameter \#3 \$headers of class GuzzleHttp\\Psr7\\ServerRequest constructor expects array\<array\<string\>\|string\>, array given\.$#'
identifier: argument.type
count: 1
path: src/ServerRequest.php
-
message: '#^Parameter \#3 \$subject of function str_replace expects array\<string\>\|string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/ServerRequest.php
-
message: '#^Parameter \#4 \$clientFilename of class GuzzleHttp\\Psr7\\UploadedFile constructor expects string\|null, mixed given\.$#'
identifier: argument.type
count: 1
path: src/ServerRequest.php
-
message: '#^Parameter \#5 \$clientMediaType of class GuzzleHttp\\Psr7\\UploadedFile constructor expects string\|null, mixed given\.$#'
identifier: argument.type
count: 1
path: src/ServerRequest.php
-
message: '#^Offset ''size'' on array\{0\: int, 1\: int, 2\: int, 3\: int, 4\: int, 5\: int, 6\: int, 7\: int, \.\.\.\} in isset\(\) always exists and is not nullable\.$#'
identifier: isset.offset
count: 1
path: src/Stream.php
-
message: '#^Property GuzzleHttp\\Psr7\\Stream\:\:\$stream \(resource\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 10
path: src/Stream.php
-
message: '#^Property GuzzleHttp\\Psr7\\Stream\:\:\$uri \(string\|null\) does not accept mixed\.$#'
identifier: assign.propertyType
count: 1
path: src/Stream.php
-
message: '#^Unreachable statement \- code above always terminates\.$#'
identifier: deadCode.unreachable
count: 1
path: src/Stream.php
-
message: '#^Cannot access offset ''stream'' on mixed\.$#'
identifier: offsetAccess.nonOffsetAccessible
count: 1
path: src/StreamWrapper.php
-
message: '#^Cannot access offset string on mixed\.$#'
identifier: offsetAccess.nonOffsetAccessible
count: 1
path: src/StreamWrapper.php
-
message: '#^Method GuzzleHttp\\Psr7\\StreamWrapper\:\:getResource\(\) should return resource but returns resource\|false\.$#'
identifier: return.type
count: 1
path: src/StreamWrapper.php
-
message: '#^Method GuzzleHttp\\Psr7\\StreamWrapper\:\:stream_stat\(\) should return array\{dev\: int, ino\: int, mode\: int, nlink\: int, uid\: int, gid\: int, rdev\: int, size\: int, \.\.\.\}\|false but returns array\{dev\: 0, ino\: 0, mode\: mixed, nlink\: 0, uid\: 0, gid\: 0, rdev\: 0, size\: int, \.\.\.\}\.$#'
identifier: return.type
count: 1
path: src/StreamWrapper.php
-
message: '#^Property GuzzleHttp\\Psr7\\StreamWrapper\:\:\$stream \(Psr\\Http\\Message\\StreamInterface\) does not accept mixed\.$#'
identifier: assign.propertyType
count: 1
path: src/StreamWrapper.php
-
message: '#^Method GuzzleHttp\\Psr7\\UploadedFile\:\:isStringNotEmpty\(\) has parameter \$param with no type specified\.$#'
identifier: missingType.parameter
count: 1
path: src/UploadedFile.php
-
message: '#^Cannot cast mixed to int\.$#'
identifier: cast.int
count: 1
path: src/Uri.php
-
message: '#^Method GuzzleHttp\\Psr7\\Uri\:\:filterPath\(\) should return string but returns string\|null\.$#'
identifier: return.type
count: 1
path: src/Uri.php
-
message: '#^Method GuzzleHttp\\Psr7\\Uri\:\:filterQueryAndFragment\(\) should return string but returns string\|null\.$#'
identifier: return.type
count: 1
path: src/Uri.php
-
message: '#^Method GuzzleHttp\\Psr7\\Uri\:\:filterUserInfoComponent\(\) should return string but returns string\|null\.$#'
identifier: return.type
count: 1
path: src/Uri.php
-
message: '#^Parameter \#1 \$callback of function array_map expects \(callable\(int\<0, 65535\>\|string\)\: mixed\)\|null, ''urldecode'' given\.$#'
identifier: argument.type
count: 1
path: src/Uri.php
-
message: '#^Parameter \#1 \$str of function rawurlencode expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Uri.php
-
message: '#^Parameter \#1 \$path of method Psr\\Http\\Message\\UriInterface\:\:withPath\(\) expects string, string\|null given\.$#'
identifier: argument.type
count: 3
path: src/UriNormalizer.php
-
message: '#^Parameter \#1 \$query of method Psr\\Http\\Message\\UriInterface\:\:withQuery\(\) expects string, string\|null given\.$#'
identifier: argument.type
count: 2
path: src/UriNormalizer.php
-
message: '#^Parameter \#1 \$str of function rawurldecode expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/UriNormalizer.php
-
message: '#^Parameter \#1 \$str of function strtoupper expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/UriNormalizer.php
-
message: '#^Strict comparison using \=\=\= between '''' and non\-falsy\-string will always evaluate to false\.$#'
identifier: identical.alwaysFalse
count: 1
path: src/UriResolver.php
-
message: '#^Binary operation "\+" between mixed and array results in an error\.$#'
identifier: binaryOp.invalid
count: 1
path: src/Utils.php
-
message: '#^Binary operation "\." between ''\:'' and mixed results in an error\.$#'
identifier: binaryOp.invalid
count: 1
path: src/Utils.php
-
message: '#^Binary operation "\.\=" between mixed and non\-falsy\-string results in an error\.$#'
identifier: assignOp.invalid
count: 1
path: src/Utils.php
-
message: '#^Cannot access offset ''Host'' on mixed\.$#'
identifier: offsetAccess.nonOffsetAccessible
count: 1
path: src/Utils.php
-
message: '#^Cannot call method getHost\(\) on mixed\.$#'
identifier: method.nonObject
count: 1
path: src/Utils.php
-
message: '#^Cannot call method getPort\(\) on mixed\.$#'
identifier: method.nonObject
count: 1
path: src/Utils.php
-
message: '#^Cannot call method getScheme\(\) on mixed\.$#'
identifier: method.nonObject
count: 1
path: src/Utils.php
-
message: '#^Cannot call method withQuery\(\) on mixed\.$#'
identifier: method.nonObject
count: 1
path: src/Utils.php
-
message: '#^Method GuzzleHttp\\Psr7\\Utils\:\:tryGetContents\(\) should return string but returns string\|false\.$#'
identifier: return.type
count: 1
path: src/Utils.php
-
message: '#^PHPDoc tag @var with type object is not subtype of native type object\.$#'
identifier: varTag.nativeType
count: 1
path: src/Utils.php
-
message: '#^Parameter \#1 \$input of function array_keys expects array, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Utils.php
-
message: '#^Parameter \#1 \$keys of static method GuzzleHttp\\Psr7\\Utils\:\:caselessRemove\(\) expects array\<int\|string\>, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Utils.php
-
message: '#^Parameter \#1 \$method of class GuzzleHttp\\Psr7\\Request constructor expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Utils.php
-
message: '#^Parameter \#1 \$method of class GuzzleHttp\\Psr7\\ServerRequest constructor expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Utils.php
-
message: '#^Parameter \#1 \$source of class GuzzleHttp\\Psr7\\PumpStream constructor expects callable\(int\)\: \(string\|false\|null\), Closure\(\)\: mixed given\.$#'
identifier: argument.type
count: 1
path: src/Utils.php
-
message: '#^Parameter \#2 \$uri of class GuzzleHttp\\Psr7\\Request constructor expects Psr\\Http\\Message\\UriInterface\|string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Utils.php
-
message: '#^Parameter \#2 \$uri of class GuzzleHttp\\Psr7\\ServerRequest constructor expects Psr\\Http\\Message\\UriInterface\|string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Utils.php
-
message: '#^Parameter \#3 \$headers of class GuzzleHttp\\Psr7\\Request constructor expects array\<array\<string\>\|string\>, array given\.$#'
identifier: argument.type
count: 1
path: src/Utils.php
-
message: '#^Parameter \#3 \$headers of class GuzzleHttp\\Psr7\\ServerRequest constructor expects array\<array\<string\>\|string\>, array given\.$#'
identifier: argument.type
count: 1
path: src/Utils.php
-
message: '#^Parameter \#4 \$body of class GuzzleHttp\\Psr7\\Request constructor expects Psr\\Http\\Message\\StreamInterface\|resource\|string\|null, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Utils.php
-
message: '#^Parameter \#4 \$body of class GuzzleHttp\\Psr7\\ServerRequest constructor expects Psr\\Http\\Message\\StreamInterface\|resource\|string\|null, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Utils.php
-
message: '#^Parameter \#5 \$version of class GuzzleHttp\\Psr7\\Request constructor expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Utils.php
-
message: '#^Parameter \#5 \$version of class GuzzleHttp\\Psr7\\ServerRequest constructor expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Utils.php
-
message: '#^Unreachable statement \- code above always terminates\.$#'
identifier: deadCode.unreachable
count: 1
path: src/Utils.php
-
message: '#^Variable \$contents might not be defined\.$#'
identifier: variable.undefined
count: 1
path: src/Utils.php
-
message: '#^Variable \$handle might not be defined\.$#'
identifier: variable.undefined
count: 1
path: src/Utils.php

11
vendor/guzzlehttp/psr7/phpstan.neon.dist

@ -1,11 +0,0 @@
includes:
- phpstan-baseline.neon
- vendor-bin/phpstan/vendor/phpstan/phpstan-deprecation-rules/rules.neon
parameters:
ignoreErrors:
-
identifier: missingType.iterableValue
level: max
paths:
- src

35
vendor/guzzlehttp/psr7/phpunit.xml.dist

@ -1,35 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
backupGlobals="true"
colors="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTestsThatDoNotTestAnything="true"
bootstrap="vendor/autoload.php"
convertDeprecationsToExceptions="true"
>
<testsuites>
<testsuite name="Guzzle PSR-7 Unit Test Suite">
<directory>tests</directory>
<exclude>tests/Integration</exclude>
</testsuite>
<testsuite name="Guzzle PSR-7 Integration Test Suite">
<directory>tests/Integration</directory>
</testsuite>
<testsuite name="PSR-17 Integration Test Suite">
<directory>./vendor/http-interop/http-factory-tests/test</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>src</directory>
</whitelist>
</filter>
<php>
<const name="REQUEST_FACTORY" value="GuzzleHttp\Psr7\HttpFactory"/>
<const name="RESPONSE_FACTORY" value="GuzzleHttp\Psr7\HttpFactory"/>
<const name="SERVER_REQUEST_FACTORY" value="GuzzleHttp\Psr7\HttpFactory"/>
<const name="STREAM_FACTORY" value="GuzzleHttp\Psr7\HttpFactory"/>
<const name="UPLOADED_FILE_FACTORY" value="GuzzleHttp\Psr7\HttpFactory"/>
<const name="URI_FACTORY" value="GuzzleHttp\Psr7\HttpFactory"/>
</php>
</phpunit>

137
vendor/guzzlehttp/psr7/psalm-baseline.xml

@ -1,137 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="5.26.1@d747f6500b38ac4f7dfc5edbcae6e4b637d7add0">
<file src="src/FnStream.php">
<InvalidFunctionCall>
<code><![CDATA[($this->_fn___toString)()]]></code>
<code><![CDATA[($this->_fn_close)()]]></code>
<code><![CDATA[($this->_fn_detach)()]]></code>
<code><![CDATA[($this->_fn_eof)()]]></code>
<code><![CDATA[($this->_fn_getContents)()]]></code>
<code><![CDATA[($this->_fn_getMetadata)($key)]]></code>
<code><![CDATA[($this->_fn_getSize)()]]></code>
<code><![CDATA[($this->_fn_isReadable)()]]></code>
<code><![CDATA[($this->_fn_isSeekable)()]]></code>
<code><![CDATA[($this->_fn_isWritable)()]]></code>
<code><![CDATA[($this->_fn_read)($length)]]></code>
<code><![CDATA[($this->_fn_rewind)()]]></code>
<code><![CDATA[($this->_fn_seek)($offset, $whence)]]></code>
<code><![CDATA[($this->_fn_tell)()]]></code>
<code><![CDATA[($this->_fn_write)($string)]]></code>
</InvalidFunctionCall>
</file>
<file src="src/Header.php">
<PossiblyUndefinedArrayOffset>
<code><![CDATA[$m[0]]]></code>
</PossiblyUndefinedArrayOffset>
</file>
<file src="src/HttpFactory.php">
<ParamNameMismatch>
<code><![CDATA[$file]]></code>
</ParamNameMismatch>
</file>
<file src="src/Message.php">
<PossiblyNullArgument>
<code><![CDATA[$matches[1] === '/' ? self::parseRequestUri($parts[1], $data['headers']) : $parts[1]]]></code>
<code><![CDATA[$parts[1]]]></code>
<code><![CDATA[$parts[1]]]></code>
</PossiblyNullArgument>
<PossiblyUndefinedArrayOffset>
<code><![CDATA[$parts[1]]]></code>
<code><![CDATA[$parts[1]]]></code>
<code><![CDATA[$parts[1]]]></code>
<code><![CDATA[$parts[1]]]></code>
</PossiblyUndefinedArrayOffset>
</file>
<file src="src/MessageTrait.php">
<LessSpecificImplementedReturnType>
<code><![CDATA[MessageInterface]]></code>
<code><![CDATA[MessageInterface]]></code>
<code><![CDATA[MessageInterface]]></code>
<code><![CDATA[MessageInterface]]></code>
<code><![CDATA[MessageInterface]]></code>
<code><![CDATA[array]]></code>
<code><![CDATA[array]]></code>
</LessSpecificImplementedReturnType>
<ParamNameMismatch>
<code><![CDATA[$header]]></code>
<code><![CDATA[$header]]></code>
<code><![CDATA[$header]]></code>
<code><![CDATA[$header]]></code>
<code><![CDATA[$header]]></code>
<code><![CDATA[$header]]></code>
</ParamNameMismatch>
</file>
<file src="src/Request.php">
<NoValue>
<code><![CDATA[$header]]></code>
</NoValue>
</file>
<file src="src/Response.php">
<RedundantCast>
<code><![CDATA[(int) $code]]></code>
<code><![CDATA[(string) $reasonPhrase]]></code>
</RedundantCast>
</file>
<file src="src/ServerRequest.php">
<InvalidArgument>
<code><![CDATA[$_SERVER['SERVER_PORT']]]></code>
</InvalidArgument>
<InvalidArrayOffset>
<code><![CDATA[$normalizedFiles[$key]]]></code>
</InvalidArrayOffset>
<InvalidReturnStatement>
<code><![CDATA[$normalizedFiles]]></code>
</InvalidReturnStatement>
<InvalidReturnType>
<code><![CDATA[UploadedFileInterface[]]]></code>
</InvalidReturnType>
<ParamNameMismatch>
<code><![CDATA[$attribute]]></code>
<code><![CDATA[$attribute]]></code>
<code><![CDATA[$attribute]]></code>
</ParamNameMismatch>
</file>
<file src="src/Stream.php">
<InvalidPropertyAssignmentValue>
<code><![CDATA[$this->stream]]></code>
</InvalidPropertyAssignmentValue>
<RedundantCast>
<code><![CDATA[(int) $whence]]></code>
</RedundantCast>
<RedundantPropertyInitializationCheck>
<code><![CDATA[isset($this->stream)]]></code>
<code><![CDATA[isset($this->stream)]]></code>
<code><![CDATA[isset($this->stream)]]></code>
<code><![CDATA[isset($this->stream)]]></code>
<code><![CDATA[isset($this->stream)]]></code>
<code><![CDATA[isset($this->stream)]]></code>
<code><![CDATA[isset($this->stream)]]></code>
<code><![CDATA[isset($this->stream)]]></code>
<code><![CDATA[isset($this->stream)]]></code>
<code><![CDATA[isset($this->stream)]]></code>
</RedundantPropertyInitializationCheck>
</file>
<file src="src/Uri.php">
<PossiblyInvalidArgument>
<code><![CDATA[$result]]></code>
</PossiblyInvalidArgument>
</file>
<file src="src/UriResolver.php">
<TypeDoesNotContainType>
<code><![CDATA['' === $relativePath]]></code>
</TypeDoesNotContainType>
</file>
<file src="src/Utils.php">
<FalsableReturnStatement>
<code><![CDATA[$contents]]></code>
</FalsableReturnStatement>
<MissingDocblockType>
<code><![CDATA[throw $ex;]]></code>
<code><![CDATA[throw $ex;]]></code>
</MissingDocblockType>
<PossiblyUndefinedVariable>
<code><![CDATA[$contents]]></code>
<code><![CDATA[$handle]]></code>
</PossiblyUndefinedVariable>
</file>
</files>

18
vendor/guzzlehttp/psr7/psalm.xml

@ -1,18 +0,0 @@
<?xml version="1.0"?>
<psalm
errorLevel="3"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
errorBaseline="psalm-baseline.xml"
findUnusedBaselineEntry="true"
findUnusedCode="false"
>
<projectFiles>
<directory name="src" />
<ignoreFiles>
<directory name="vendor" />
</ignoreFiles>
</projectFiles>
</psalm>

221
vendor/guzzlehttp/psr7/tests/AppendStreamTest.php

@ -1,221 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\AppendStream;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\StreamInterface;
class AppendStreamTest extends TestCase
{
public function testValidatesStreamsAreReadable(): void
{
$a = new AppendStream();
$s = $this->createMock(StreamInterface::class);
$s->expects(self::once())
->method('isReadable')
->willReturn(false);
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Each stream must be readable');
$a->addStream($s);
}
public function testValidatesSeekType(): void
{
$a = new AppendStream();
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('The AppendStream can only seek with SEEK_SET');
$a->seek(100, SEEK_CUR);
}
public function testTriesToRewindOnSeek(): void
{
$a = new AppendStream();
$s = $this->createMock(StreamInterface::class);
$s->expects(self::once())
->method('isReadable')
->willReturn(true);
$s->expects(self::once())
->method('isSeekable')
->willReturn(true);
$s->expects(self::once())
->method('rewind')
->willThrowException(new \RuntimeException());
$a->addStream($s);
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('Unable to seek stream 0 of the AppendStream');
$a->seek(10);
}
public function testSeeksToPositionByReading(): void
{
$a = new AppendStream([
Psr7\Utils::streamFor('foo'),
Psr7\Utils::streamFor('bar'),
Psr7\Utils::streamFor('baz'),
]);
$a->seek(3);
self::assertSame(3, $a->tell());
self::assertSame('bar', $a->read(3));
$a->seek(6);
self::assertSame(6, $a->tell());
self::assertSame('baz', $a->read(3));
}
public function testDetachWithoutStreams(): void
{
$s = new AppendStream();
$s->detach();
self::assertSame(0, $s->getSize());
self::assertTrue($s->eof());
self::assertTrue($s->isReadable());
self::assertSame('', (string) $s);
self::assertTrue($s->isSeekable());
self::assertFalse($s->isWritable());
}
public function testDetachesEachStream(): void
{
$handle = fopen('php://temp', 'r');
$s1 = Psr7\Utils::streamFor($handle);
$s2 = Psr7\Utils::streamFor('bar');
$a = new AppendStream([$s1, $s2]);
$a->detach();
self::assertSame(0, $a->getSize());
self::assertTrue($a->eof());
self::assertTrue($a->isReadable());
self::assertSame('', (string) $a);
self::assertTrue($a->isSeekable());
self::assertFalse($a->isWritable());
self::assertNull($s1->detach());
self::assertIsResource($handle, 'resource is not closed when detaching');
fclose($handle);
}
public function testClosesEachStream(): void
{
$handle = fopen('php://temp', 'r');
$s1 = Psr7\Utils::streamFor($handle);
$s2 = Psr7\Utils::streamFor('bar');
$a = new AppendStream([$s1, $s2]);
$a->close();
self::assertSame(0, $a->getSize());
self::assertTrue($a->eof());
self::assertTrue($a->isReadable());
self::assertSame('', (string) $a);
self::assertTrue($a->isSeekable());
self::assertFalse($a->isWritable());
self::assertFalse(is_resource($handle));
}
public function testIsNotWritable(): void
{
$a = new AppendStream([Psr7\Utils::streamFor('foo')]);
self::assertFalse($a->isWritable());
self::assertTrue($a->isSeekable());
self::assertTrue($a->isReadable());
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('Cannot write to an AppendStream');
$a->write('foo');
}
public function testDoesNotNeedStreams(): void
{
$a = new AppendStream();
self::assertSame('', (string) $a);
}
public function testCanReadFromMultipleStreams(): void
{
$a = new AppendStream([
Psr7\Utils::streamFor('foo'),
Psr7\Utils::streamFor('bar'),
Psr7\Utils::streamFor('baz'),
]);
self::assertFalse($a->eof());
self::assertSame(0, $a->tell());
self::assertSame('foo', $a->read(3));
self::assertSame('bar', $a->read(3));
self::assertSame('baz', $a->read(3));
self::assertSame('', $a->read(1));
self::assertTrue($a->eof());
self::assertSame(9, $a->tell());
self::assertSame('foobarbaz', (string) $a);
}
public function testCanDetermineSizeFromMultipleStreams(): void
{
$a = new AppendStream([
Psr7\Utils::streamFor('foo'),
Psr7\Utils::streamFor('bar'),
]);
self::assertSame(6, $a->getSize());
$s = $this->createMock(StreamInterface::class);
$s->expects(self::once())
->method('isSeekable')
->willReturn(false);
$s->expects(self::once())
->method('isReadable')
->willReturn(true);
$a->addStream($s);
self::assertNull($a->getSize());
}
/**
* @requires PHP < 7.4
*/
public function testCatchesExceptionsWhenCastingToString(): void
{
$s = $this->createMock(StreamInterface::class);
$s->expects(self::once())
->method('isSeekable')
->willReturn(true);
$s->expects(self::once())
->method('read')
->willThrowException(new \RuntimeException('foo'));
$s->expects(self::once())
->method('isReadable')
->willReturn(true);
$s->expects(self::any())
->method('eof')
->willReturn(false);
$a = new AppendStream([$s]);
self::assertFalse($a->eof());
$errors = [];
set_error_handler(static function (int $errorNumber, string $errorMessage) use (&$errors): bool {
$errors[] = ['number' => $errorNumber, 'message' => $errorMessage];
return true;
});
(string) $a;
restore_error_handler();
self::assertCount(1, $errors);
self::assertSame(E_USER_ERROR, $errors[0]['number']);
self::assertStringStartsWith('GuzzleHttp\Psr7\AppendStream::__toString exception:', $errors[0]['message']);
}
public function testReturnsEmptyMetadata(): void
{
$s = new AppendStream();
self::assertSame([], $s->getMetadata());
self::assertNull($s->getMetadata('foo'));
}
}

65
vendor/guzzlehttp/psr7/tests/BufferStreamTest.php

@ -1,65 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7\BufferStream;
use PHPUnit\Framework\TestCase;
class BufferStreamTest extends TestCase
{
public function testHasMetadata(): void
{
$b = new BufferStream(10);
self::assertTrue($b->isReadable());
self::assertTrue($b->isWritable());
self::assertFalse($b->isSeekable());
self::assertNull($b->getMetadata('foo'));
self::assertSame(10, $b->getMetadata('hwm'));
self::assertSame([], $b->getMetadata());
}
public function testRemovesReadDataFromBuffer(): void
{
$b = new BufferStream();
self::assertSame(3, $b->write('foo'));
self::assertSame(3, $b->getSize());
self::assertFalse($b->eof());
self::assertSame('foo', $b->read(10));
self::assertTrue($b->eof());
self::assertSame('', $b->read(10));
}
public function testCanCastToStringOrGetContents(): void
{
$b = new BufferStream();
$b->write('foo');
$b->write('baz');
self::assertSame('foo', $b->read(3));
$b->write('bar');
self::assertSame('bazbar', (string) $b);
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('Cannot determine the position of a BufferStream');
$b->tell();
}
public function testDetachClearsBuffer(): void
{
$b = new BufferStream();
$b->write('foo');
$b->detach();
self::assertTrue($b->eof());
self::assertSame(3, $b->write('abc'));
self::assertSame('abc', $b->read(10));
}
public function testExceedingHighwaterMarkReturnsFalseButStillBuffers(): void
{
$b = new BufferStream(5);
self::assertSame(3, $b->write('hi '));
self::assertSame(0, $b->write('hello'));
self::assertSame('hi hello', (string) $b);
self::assertSame(4, $b->write('test'));
}
}

200
vendor/guzzlehttp/psr7/tests/CachingStreamTest.php

@ -1,200 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\CachingStream;
use GuzzleHttp\Psr7\Stream;
use PHPUnit\Framework\TestCase;
/**
* @covers \GuzzleHttp\Psr7\CachingStream
*/
class CachingStreamTest extends TestCase
{
/** @var CachingStream */
private $body;
/** @var Stream */
private $decorated;
protected function setUp(): void
{
$this->decorated = Psr7\Utils::streamFor('testing');
$this->body = new CachingStream($this->decorated);
}
protected function tearDown(): void
{
$this->decorated->close();
$this->body->close();
}
public function testUsesRemoteSizeIfAvailable(): void
{
$body = Psr7\Utils::streamFor('test');
$caching = new CachingStream($body);
self::assertSame(4, $caching->getSize());
}
public function testUsesRemoteSizeIfNotAvailable(): void
{
$body = new Psr7\PumpStream(function () {
return 'a';
});
$caching = new CachingStream($body);
self::assertNull($caching->getSize());
}
public function testReadsUntilCachedToByte(): void
{
$this->body->seek(5);
self::assertSame('n', $this->body->read(1));
$this->body->seek(0);
self::assertSame('t', $this->body->read(1));
}
public function testCanSeekNearEndWithSeekEnd(): void
{
$baseStream = Psr7\Utils::streamFor(implode('', range('a', 'z')));
$cached = new CachingStream($baseStream);
$cached->seek(-1, SEEK_END);
self::assertSame(25, $baseStream->tell());
self::assertSame('z', $cached->read(1));
self::assertSame(26, $cached->getSize());
}
public function testCanSeekToEndWithSeekEnd(): void
{
$baseStream = Psr7\Utils::streamFor(implode('', range('a', 'z')));
$cached = new CachingStream($baseStream);
$cached->seek(0, SEEK_END);
self::assertSame(26, $baseStream->tell());
self::assertSame('', $cached->read(1));
self::assertSame(26, $cached->getSize());
}
public function testCanUseSeekEndWithUnknownSize(): void
{
$baseStream = Psr7\Utils::streamFor('testing');
$decorated = Psr7\FnStream::decorate($baseStream, [
'getSize' => function () {
return null;
},
]);
$cached = new CachingStream($decorated);
$cached->seek(-1, SEEK_END);
self::assertSame('g', $cached->read(1));
}
public function testRewind(): void
{
$a = Psr7\Utils::streamFor('foo');
$d = new CachingStream($a);
self::assertSame('foo', $d->read(3));
$d->rewind();
self::assertSame('foo', $d->read(3));
}
public function testCanSeekToReadBytes(): void
{
self::assertSame('te', $this->body->read(2));
$this->body->seek(0);
self::assertSame('test', $this->body->read(4));
self::assertSame(4, $this->body->tell());
$this->body->seek(2);
self::assertSame(2, $this->body->tell());
$this->body->seek(2, SEEK_CUR);
self::assertSame(4, $this->body->tell());
self::assertSame('ing', $this->body->read(3));
}
public function testCanSeekToReadBytesWithPartialBodyReturned(): void
{
$stream = fopen('php://temp', 'r+');
fwrite($stream, 'testing');
fseek($stream, 0);
$this->decorated = $this->getMockBuilder(Stream::class)
->setConstructorArgs([$stream])
->onlyMethods(['read'])
->getMock();
$this->decorated->expects(self::exactly(2))
->method('read')
->willReturnCallback(function (int $length) use ($stream) {
return fread($stream, 2);
});
$this->body = new CachingStream($this->decorated);
self::assertSame(0, $this->body->tell());
$this->body->seek(4, SEEK_SET);
self::assertSame(4, $this->body->tell());
$this->body->seek(0);
self::assertSame('test', $this->body->read(4));
}
public function testWritesToBufferStream(): void
{
$this->body->read(2);
$this->body->write('hi');
$this->body->seek(0);
self::assertSame('tehiing', (string) $this->body);
}
public function testSkipsOverwrittenBytes(): void
{
$decorated = Psr7\Utils::streamFor(
implode("\n", array_map(function ($n) {
return str_pad((string) $n, 4, '0', STR_PAD_LEFT);
}, range(0, 25)))
);
$body = new CachingStream($decorated);
self::assertSame("0000\n", Psr7\Utils::readLine($body));
self::assertSame("0001\n", Psr7\Utils::readLine($body));
// Write over part of the body yet to be read, so skip some bytes
self::assertSame(5, $body->write("TEST\n"));
// Read, which skips bytes, then reads
self::assertSame("0003\n", Psr7\Utils::readLine($body));
self::assertSame("0004\n", Psr7\Utils::readLine($body));
self::assertSame("0005\n", Psr7\Utils::readLine($body));
// Overwrite part of the cached body (so don't skip any bytes)
$body->seek(5);
self::assertSame(5, $body->write("ABCD\n"));
self::assertSame("TEST\n", Psr7\Utils::readLine($body));
self::assertSame("0003\n", Psr7\Utils::readLine($body));
self::assertSame("0004\n", Psr7\Utils::readLine($body));
self::assertSame("0005\n", Psr7\Utils::readLine($body));
self::assertSame("0006\n", Psr7\Utils::readLine($body));
self::assertSame(5, $body->write("1234\n"));
// Seek to 0 and ensure the overwritten bit is replaced
$body->seek(0);
self::assertSame("0000\nABCD\nTEST\n0003\n0004\n0005\n0006\n1234\n0008\n0009\n", $body->read(50));
// Ensure that casting it to a string does not include the bit that was overwritten
self::assertStringContainsString("0000\nABCD\nTEST\n0003\n0004\n0005\n0006\n1234\n0008\n0009\n", (string) $body);
}
public function testClosesBothStreams(): void
{
$s = fopen('php://temp', 'r');
$a = Psr7\Utils::streamFor($s);
$d = new CachingStream($a);
$d->close();
self::assertFalse(is_resource($s));
}
public function testEnsuresValidWhence(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Invalid whence');
$this->body->seek(10, -123456);
}
}

30
vendor/guzzlehttp/psr7/tests/DroppingStreamTest.php

@ -1,30 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7\BufferStream;
use GuzzleHttp\Psr7\DroppingStream;
use PHPUnit\Framework\TestCase;
class DroppingStreamTest extends TestCase
{
public function testBeginsDroppingWhenSizeExceeded(): void
{
$stream = new BufferStream();
$drop = new DroppingStream($stream, 5);
self::assertSame(3, $drop->write('hel'));
self::assertSame(2, $drop->write('lo'));
self::assertSame(5, $drop->getSize());
self::assertSame('hello', $drop->read(5));
self::assertSame(0, $drop->getSize());
$drop->write('12345678910');
self::assertSame(5, $stream->getSize());
self::assertSame(5, $drop->getSize());
self::assertSame('12345', (string) $drop);
self::assertSame(0, $drop->getSize());
$drop->write('hello');
self::assertSame(0, $drop->write('test'));
}
}

128
vendor/guzzlehttp/psr7/tests/FnStreamTest.php

@ -1,128 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\FnStream;
use PHPUnit\Framework\TestCase;
/**
* @covers \GuzzleHttp\Psr7\FnStream
*/
class FnStreamTest extends TestCase
{
public function testThrowsWhenNotImplemented(): void
{
$this->expectException(\BadMethodCallException::class);
$this->expectExceptionMessage('seek() is not implemented in the FnStream');
(new FnStream([]))->seek(1);
}
public function testProxiesToFunction(): void
{
$s = new FnStream([
'read' => function ($len) {
$this->assertSame(3, $len);
return 'foo';
},
]);
self::assertSame('foo', $s->read(3));
}
public function testCanCloseOnDestruct(): void
{
$called = false;
$s = new FnStream([
'close' => function () use (&$called): void {
$called = true;
},
]);
unset($s);
self::assertTrue($called);
}
public function testDoesNotRequireClose(): void
{
$s = new FnStream([]);
unset($s);
self::assertTrue(true); // strict mode requires an assertion
}
public function testDecoratesStream(): void
{
$a = Psr7\Utils::streamFor('foo');
$b = FnStream::decorate($a, []);
self::assertSame(3, $b->getSize());
self::assertSame($b->isWritable(), true);
self::assertSame($b->isReadable(), true);
self::assertSame($b->isSeekable(), true);
self::assertSame($b->read(3), 'foo');
self::assertSame($b->tell(), 3);
self::assertSame($a->tell(), 3);
self::assertSame('', $a->read(1));
self::assertSame($b->eof(), true);
self::assertSame($a->eof(), true);
$b->seek(0);
self::assertSame('foo', (string) $b);
$b->seek(0);
self::assertSame('foo', $b->getContents());
self::assertSame($a->getMetadata(), $b->getMetadata());
$b->seek(0, SEEK_END);
$b->write('bar');
self::assertSame('foobar', (string) $b);
self::assertIsResource($b->detach());
$b->close();
}
public function testDecoratesWithCustomizations(): void
{
$called = false;
$a = Psr7\Utils::streamFor('foo');
$b = FnStream::decorate($a, [
'read' => function ($len) use (&$called, $a) {
$called = true;
return $a->read($len);
},
]);
self::assertSame('foo', $b->read(3));
self::assertTrue($called);
}
public function testDoNotAllowUnserialization(): void
{
$a = new FnStream([]);
$b = serialize($a);
$this->expectException(\LogicException::class);
$this->expectExceptionMessage('FnStream should never be unserialized');
unserialize($b);
}
/**
* @requires PHP < 7.4
*/
public function testThatConvertingStreamToStringWillTriggerErrorAndWillReturnEmptyString(): void
{
$a = new FnStream([
'__toString' => function (): void {
throw new \Exception();
},
]);
$errors = [];
set_error_handler(function (int $errorNumber, string $errorMessage) use (&$errors): void {
$errors[] = ['number' => $errorNumber, 'message' => $errorMessage];
});
(string) $a;
restore_error_handler();
self::assertCount(1, $errors);
self::assertSame(E_USER_ERROR, $errors[0]['number']);
self::assertStringStartsWith('GuzzleHttp\Psr7\FnStream::__toString exception:', $errors[0]['message']);
}
}

13
vendor/guzzlehttp/psr7/tests/HasToString.php

@ -1,13 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
class HasToString
{
public function __toString(): string
{
return 'foo';
}
}

182
vendor/guzzlehttp/psr7/tests/HeaderTest.php

@ -1,182 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7;
use PHPUnit\Framework\TestCase;
class HeaderTest extends TestCase
{
public function parseParamsProvider(): array
{
$res1 = [
[
'<http:/.../front.jpeg>',
'rel' => 'front',
'type' => 'image/jpeg',
],
[
'<http://.../back.jpeg>',
'rel' => 'back',
'type' => 'image/jpeg',
],
];
return [
[
'<http:/.../front.jpeg>; rel="front"; type="image/jpeg", <http://.../back.jpeg>; rel=back; type="image/jpeg"',
$res1,
],
[
'<http:/.../front.jpeg>; rel="front"; type="image/jpeg",<http://.../back.jpeg>; rel=back; type="image/jpeg"',
$res1,
],
[
'foo="baz"; bar=123, boo, test="123", foobar="foo;bar"',
[
['foo' => 'baz', 'bar' => '123'],
['boo'],
['test' => '123'],
['foobar' => 'foo;bar'],
],
],
[
'<http://.../side.jpeg?test=1>; rel="side"; type="image/jpeg",<http://.../side.jpeg?test=2>; rel=side; type="image/jpeg"',
[
['<http://.../side.jpeg?test=1>', 'rel' => 'side', 'type' => 'image/jpeg'],
['<http://.../side.jpeg?test=2>', 'rel' => 'side', 'type' => 'image/jpeg'],
],
],
[
'',
[],
],
];
}
/**
* @dataProvider parseParamsProvider
*/
public function testParseParams($header, $result): void
{
self::assertSame($result, Psr7\Header::parse($header));
}
public function normalizeProvider(): array
{
return [
[
'',
[],
],
[
['a, b', 'c', 'd, e'],
['a', 'b', 'c', 'd', 'e'],
],
// Example 'accept-encoding'
[
'gzip, br',
['gzip', 'br'],
],
// https://httpwg.org/specs/rfc7231.html#rfc.section.5.3.2
[
'text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c',
['text/plain; q=0.5', 'text/html', 'text/x-dvi; q=0.8', 'text/x-c'],
],
// Example 'If-None-Match' with comma within an ETag
[
'"foo", "foo,bar", "bar"',
['"foo"', '"foo,bar"', '"bar"'],
],
// https://httpwg.org/specs/rfc7234.html#cache.control.extensions
[
'private, community="UCI"',
['private', 'community="UCI"'],
],
// The Cache-Control example with a comma within a community
[
'private, community="Guzzle,Psr7"',
['private', 'community="Guzzle,Psr7"'],
],
// The Cache-Control example with an escaped space (quoted-pair) within a community
[
'private, community="Guzzle\\ Psr7"',
['private', 'community="Guzzle\\ Psr7"'],
],
// The Cache-Control example with an escaped quote (quoted-pair) within a community
[
'private, community="Guzzle\\"Psr7"',
['private', 'community="Guzzle\\"Psr7"'],
],
// The Cache-Control example with an escaped quote (quoted-pair) and a comma within a community
[
'private, community="Guzzle\\",Psr7"',
['private', 'community="Guzzle\\",Psr7"'],
],
// The Cache-Control example with an escaped backslash (quoted-pair) within a community
[
'private, community="Guzzle\\\\Psr7"',
['private', 'community="Guzzle\\\\Psr7"'],
],
// The Cache-Control example with an escaped backslash (quoted-pair) within a community
[
'private, community="Guzzle\\\\", Psr7',
['private', 'community="Guzzle\\\\"', 'Psr7'],
],
// https://httpwg.org/specs/rfc7230.html#rfc.section.7
[
'foo ,bar,',
['foo', 'bar'],
],
// https://httpwg.org/specs/rfc7230.html#rfc.section.7
[
'foo , ,bar,charlie ',
['foo', 'bar', 'charlie'],
],
[
"<https://example.gitlab.com>; rel=\"first\",\n<https://example.gitlab.com>; rel=\"next\",\n<https://example.gitlab.com>; rel=\"prev\",\n<https://example.gitlab.com>; rel=\"last\",",
['<https://example.gitlab.com>; rel="first"', '<https://example.gitlab.com>; rel="next"', '<https://example.gitlab.com>; rel="prev"', '<https://example.gitlab.com>; rel="last"'],
],
];
}
/**
* @dataProvider normalizeProvider
*/
public function testNormalize($header, $result): void
{
self::assertSame($result, Psr7\Header::normalize([$header]));
self::assertSame($result, Psr7\Header::normalize($header));
}
/**
* @dataProvider normalizeProvider
*/
public function testSplitList($header, $result): void
{
self::assertSame($result, Psr7\Header::splitList($header));
}
public function testSplitListRejectsNestedArrays(): void
{
$this->expectException(\TypeError::class);
Psr7\Header::splitList([['foo']]);
}
public function testSplitListArrayContainingNonStrings(): void
{
$this->expectException(\TypeError::class);
Psr7\Header::splitList(['foo', 'bar', 1, false]);
}
public function testSplitListRejectsNonStrings(): void
{
$this->expectException(\TypeError::class);
Psr7\Header::splitList(false);
}
}

97
vendor/guzzlehttp/psr7/tests/InflateStreamTest.php

@ -1,97 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\InflateStream;
use GuzzleHttp\Psr7\NoSeekStream;
use PHPUnit\Framework\TestCase;
/**
* @requires extension zlib
*/
class InflateStreamTest extends TestCase
{
public function testInflatesRfc1952Streams(): void
{
$content = gzencode('test');
$a = Psr7\Utils::streamFor($content);
$b = new InflateStream($a);
self::assertSame('test', (string) $b);
}
public function testInflatesStreamsRfc1952WithFilename(): void
{
$content = $this->getGzipStringWithFilename('test');
$a = Psr7\Utils::streamFor($content);
$b = new InflateStream($a);
self::assertSame('test', (string) $b);
}
public function testInflatesRfc1950Streams(): void
{
$content = gzcompress('test');
$a = Psr7\Utils::streamFor($content);
$b = new InflateStream($a);
self::assertSame('test', (string) $b);
}
public function testInflatesRfc1952StreamsWithExtraFlags(): void
{
$content = gzdeflate('test'); // RFC 1951. Raw deflate. No header.
// +---+---+---+---+---+---+---+---+---+---+
// |ID1|ID2|CM |FLG| MTIME |XFL|OS | (more-->)
// +---+---+---+---+---+---+---+---+---+---+
$header = "\x1f\x8B\x08";
// set flags FHCRC, FEXTRA, FNAME and FCOMMENT
$header .= chr(0b00011110);
$header .= "\x00\x00\x00\x00"; // MTIME
$header .= "\x02\x03"; // XFL, OS
// 4 byte extra data
$header .= "\x04\x00\x41\x70\x00\x00"; /* XLEN + EXTRA */
// file name (2 bytes + terminator)
$header .= "\x41\x70\x00";
// file comment (3 bytes + terminator)
$header .= "\x41\x42\x43\x00";
// crc16
$header .= pack('v', crc32($header));
$a = Psr7\Utils::streamFor($header.$content);
$b = new InflateStream($a);
self::assertSame('test', (string) $b);
}
public function testInflatesStreamsPreserveSeekable(): void
{
$content = gzencode('test');
$seekable = Psr7\Utils::streamFor($content);
$seekableInflate = new InflateStream($seekable);
self::assertTrue($seekableInflate->isSeekable());
self::assertSame('test', (string) $seekableInflate);
$nonSeekable = new NoSeekStream(Psr7\Utils::streamFor($content));
$nonSeekableInflate = new InflateStream($nonSeekable);
self::assertFalse($nonSeekableInflate->isSeekable());
self::assertSame('test', (string) $nonSeekableInflate);
}
private function getGzipStringWithFilename($original_string)
{
$gzipped = bin2hex(gzencode($original_string));
$header = substr($gzipped, 0, 20);
// set FNAME flag
$header[6] = 0;
$header[7] = 8;
// make a dummy filename
$filename = '64756d6d7900';
$rest = substr($gzipped, 20);
return hex2bin($header.$filename.$rest);
}
}

44
vendor/guzzlehttp/psr7/tests/Integration/ServerRequestFromGlobalsTest.php

@ -1,44 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7\Integration;
use PHPUnit\Framework\TestCase;
class ServerRequestFromGlobalsTest extends TestCase
{
protected function setUp(): void
{
if (false === $this->getServerUri()) {
self::markTestSkipped();
}
parent::setUp();
}
public function testBodyExists(): void
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $this->getServerUri());
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, 'foobar');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($curl);
curl_close($curl);
self::assertNotFalse($response);
$data = json_decode($response, true);
self::assertIsArray($data);
self::assertArrayHasKey('method', $data);
self::assertArrayHasKey('uri', $data);
self::assertArrayHasKey('body', $data);
self::assertEquals('foobar', $data['body']);
}
private function getServerUri()
{
return $_SERVER['TEST_SERVER'] ?? false;
}
}

15
vendor/guzzlehttp/psr7/tests/Integration/server.php

@ -1,15 +0,0 @@
<?php
declare(strict_types=1);
require dirname(__DIR__, 2).'/vendor/autoload.php';
$request = GuzzleHttp\Psr7\ServerRequest::fromGlobals();
$output = [
'method' => $request->getMethod(),
'uri' => $request->getUri()->__toString(),
'body' => $request->getBody()->__toString(),
];
echo json_encode($output);

68
vendor/guzzlehttp/psr7/tests/LazyOpenStreamTest.php

@ -1,68 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7\LazyOpenStream;
use PHPUnit\Framework\TestCase;
class LazyOpenStreamTest extends TestCase
{
private $fname;
protected function setUp(): void
{
$this->fname = tempnam(sys_get_temp_dir(), 'tfile');
if (file_exists($this->fname)) {
unlink($this->fname);
}
}
protected function tearDown(): void
{
if (file_exists($this->fname)) {
unlink($this->fname);
}
}
public function testOpensLazily(): void
{
$l = new LazyOpenStream($this->fname, 'w+');
$l->write('foo');
self::assertIsArray($l->getMetadata());
self::assertFileExists($this->fname);
self::assertSame('foo', file_get_contents($this->fname));
self::assertSame('foo', (string) $l);
}
public function testProxiesToFile(): void
{
file_put_contents($this->fname, 'foo');
$l = new LazyOpenStream($this->fname, 'r');
self::assertSame('foo', $l->read(4));
self::assertTrue($l->eof());
self::assertSame(3, $l->tell());
self::assertTrue($l->isReadable());
self::assertTrue($l->isSeekable());
self::assertFalse($l->isWritable());
$l->seek(1);
self::assertSame('oo', $l->getContents());
self::assertSame('foo', (string) $l);
self::assertSame(3, $l->getSize());
self::assertIsArray($l->getMetadata());
$l->close();
}
public function testDetachesUnderlyingStream(): void
{
file_put_contents($this->fname, 'foo');
$l = new LazyOpenStream($this->fname, 'r');
$r = $l->detach();
self::assertIsResource($r);
fseek($r, 0);
self::assertSame('foo', stream_get_contents($r));
fclose($r);
}
}

165
vendor/guzzlehttp/psr7/tests/LimitStreamTest.php

@ -1,165 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\FnStream;
use GuzzleHttp\Psr7\LimitStream;
use GuzzleHttp\Psr7\NoSeekStream;
use GuzzleHttp\Psr7\Stream;
use PHPUnit\Framework\TestCase;
/**
* @covers \GuzzleHttp\Psr7\LimitStream
*/
class LimitStreamTest extends TestCase
{
/** @var LimitStream */
private $body;
/** @var Stream */
private $decorated;
protected function setUp(): void
{
$this->decorated = Psr7\Utils::streamFor(fopen(__FILE__, 'r'));
$this->body = new LimitStream($this->decorated, 10, 3);
}
public function testReturnsSubset(): void
{
$body = new LimitStream(Psr7\Utils::streamFor('foo'), -1, 1);
self::assertSame('oo', (string) $body);
self::assertTrue($body->eof());
$body->seek(0);
self::assertFalse($body->eof());
self::assertSame('oo', $body->read(100));
self::assertSame('', $body->read(1));
self::assertTrue($body->eof());
}
public function testReturnsSubsetWhenCastToString(): void
{
$body = Psr7\Utils::streamFor('foo_baz_bar');
$limited = new LimitStream($body, 3, 4);
self::assertSame('baz', (string) $limited);
}
public function testReturnsSubsetOfEmptyBodyWhenCastToString(): void
{
$body = Psr7\Utils::streamFor('01234567891234');
$limited = new LimitStream($body, 0, 10);
self::assertSame('', (string) $limited);
}
public function testReturnsSpecificSubsetOBodyWhenCastToString(): void
{
$body = Psr7\Utils::streamFor('0123456789abcdef');
$limited = new LimitStream($body, 3, 10);
self::assertSame('abc', (string) $limited);
}
public function testSeeksWhenConstructed(): void
{
self::assertSame(0, $this->body->tell());
self::assertSame(3, $this->decorated->tell());
}
public function testAllowsBoundedSeek(): void
{
$this->body->seek(100);
self::assertSame(10, $this->body->tell());
self::assertSame(13, $this->decorated->tell());
$this->body->seek(0);
self::assertSame(0, $this->body->tell());
self::assertSame(3, $this->decorated->tell());
try {
$this->body->seek(-10);
self::fail();
} catch (\RuntimeException $e) {
}
self::assertSame(0, $this->body->tell());
self::assertSame(3, $this->decorated->tell());
$this->body->seek(5);
self::assertSame(5, $this->body->tell());
self::assertSame(8, $this->decorated->tell());
// Fail
try {
$this->body->seek(1000, SEEK_END);
self::fail();
} catch (\RuntimeException $e) {
}
}
public function testReadsOnlySubsetOfData(): void
{
$data = $this->body->read(100);
self::assertSame(10, strlen($data));
self::assertSame('', $this->body->read(1000));
$this->body->setOffset(10);
$newData = $this->body->read(100);
self::assertSame(10, strlen($newData));
self::assertNotSame($data, $newData);
}
public function testThrowsWhenCurrentGreaterThanOffsetSeek(): void
{
$a = Psr7\Utils::streamFor('foo_bar');
$b = new NoSeekStream($a);
$c = new LimitStream($b);
$a->getContents();
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('Could not seek to stream offset 2');
$c->setOffset(2);
}
public function testCanGetContentsWithoutSeeking(): void
{
$a = Psr7\Utils::streamFor('foo_bar');
$b = new NoSeekStream($a);
$c = new LimitStream($b);
self::assertSame('foo_bar', $c->getContents());
}
public function testClaimsConsumedWhenReadLimitIsReached(): void
{
self::assertFalse($this->body->eof());
$this->body->read(1000);
self::assertTrue($this->body->eof());
}
public function testContentLengthIsBounded(): void
{
self::assertSame(10, $this->body->getSize());
}
public function testGetContentsIsBasedOnSubset(): void
{
$body = new LimitStream(Psr7\Utils::streamFor('foobazbar'), 3, 3);
self::assertSame('baz', $body->getContents());
}
public function testReturnsNullIfSizeCannotBeDetermined(): void
{
$a = new FnStream([
'getSize' => function () {
return null;
},
'tell' => function () {
return 0;
},
]);
$b = new LimitStream($a);
self::assertNull($b->getSize());
}
public function testLengthLessOffsetWhenNoLimitSize(): void
{
$a = Psr7\Utils::streamFor('foo_bar');
$b = new LimitStream($a, -1, 4);
self::assertSame(3, $b->getSize());
}
}

299
vendor/guzzlehttp/psr7/tests/MessageTest.php

@ -1,299 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\FnStream;
use PHPUnit\Framework\TestCase;
class MessageTest extends TestCase
{
public function testConvertsRequestsToStrings(): void
{
$request = new Psr7\Request('PUT', 'http://foo.com/hi?123', [
'Baz' => 'bar',
'Qux' => 'ipsum',
], 'hello', '1.0');
self::assertSame(
"PUT /hi?123 HTTP/1.0\r\nHost: foo.com\r\nBaz: bar\r\nQux: ipsum\r\n\r\nhello",
Psr7\Message::toString($request)
);
}
public function testConvertsResponsesToStrings(): void
{
$response = new Psr7\Response(200, [
'Baz' => 'bar',
'Qux' => 'ipsum',
], 'hello', '1.0', 'FOO');
self::assertSame(
"HTTP/1.0 200 FOO\r\nBaz: bar\r\nQux: ipsum\r\n\r\nhello",
Psr7\Message::toString($response)
);
}
public function testCorrectlyRendersSetCookieHeadersToString(): void
{
$response = new Psr7\Response(200, [
'Set-Cookie' => ['bar', 'baz', 'qux'],
], 'hello', '1.0', 'FOO');
self::assertSame(
"HTTP/1.0 200 FOO\r\nSet-Cookie: bar\r\nSet-Cookie: baz\r\nSet-Cookie: qux\r\n\r\nhello",
Psr7\Message::toString($response)
);
}
public function testRewindsBody(): void
{
$body = Psr7\Utils::streamFor('abc');
$res = new Psr7\Response(200, [], $body);
Psr7\Message::rewindBody($res);
self::assertSame(0, $body->tell());
$body->rewind();
Psr7\Message::rewindBody($res);
self::assertSame(0, $body->tell());
}
public function testThrowsWhenBodyCannotBeRewound(): void
{
$body = Psr7\Utils::streamFor('abc');
$body->read(1);
$body = FnStream::decorate($body, [
'rewind' => function (): void {
throw new \RuntimeException('a');
},
]);
$res = new Psr7\Response(200, [], $body);
$this->expectException(\RuntimeException::class);
Psr7\Message::rewindBody($res);
}
public function testParsesRequestMessages(): void
{
$req = "GET /abc HTTP/1.0\r\nHost: foo.com\r\nFoo: Bar\r\nBaz: Bam\r\nBaz: Qux\r\n\r\nTest";
$request = Psr7\Message::parseRequest($req);
self::assertSame('GET', $request->getMethod());
self::assertSame('/abc', $request->getRequestTarget());
self::assertSame('1.0', $request->getProtocolVersion());
self::assertSame('foo.com', $request->getHeaderLine('Host'));
self::assertSame('Bar', $request->getHeaderLine('Foo'));
self::assertSame('Bam, Qux', $request->getHeaderLine('Baz'));
self::assertSame('Test', (string) $request->getBody());
self::assertSame('http://foo.com/abc', (string) $request->getUri());
}
public function testParsesRequestMessagesWithHttpsScheme(): void
{
$req = "PUT /abc?baz=bar HTTP/1.1\r\nHost: foo.com:443\r\n\r\n";
$request = Psr7\Message::parseRequest($req);
self::assertSame('PUT', $request->getMethod());
self::assertSame('/abc?baz=bar', $request->getRequestTarget());
self::assertSame('1.1', $request->getProtocolVersion());
self::assertSame('foo.com:443', $request->getHeaderLine('Host'));
self::assertSame('', (string) $request->getBody());
self::assertSame('https://foo.com/abc?baz=bar', (string) $request->getUri());
}
public function testParsesRequestMessagesWithUriWhenHostIsNotFirst(): void
{
$req = "PUT / HTTP/1.1\r\nFoo: Bar\r\nHost: foo.com\r\n\r\n";
$request = Psr7\Message::parseRequest($req);
self::assertSame('PUT', $request->getMethod());
self::assertSame('/', $request->getRequestTarget());
self::assertSame('http://foo.com/', (string) $request->getUri());
}
public function testParsesRequestMessagesWithFullUri(): void
{
$req = "GET https://www.google.com:443/search?q=foobar HTTP/1.1\r\nHost: www.google.com\r\n\r\n";
$request = Psr7\Message::parseRequest($req);
self::assertSame('GET', $request->getMethod());
self::assertSame('https://www.google.com:443/search?q=foobar', $request->getRequestTarget());
self::assertSame('1.1', $request->getProtocolVersion());
self::assertSame('www.google.com', $request->getHeaderLine('Host'));
self::assertSame('', (string) $request->getBody());
self::assertSame('https://www.google.com/search?q=foobar', (string) $request->getUri());
}
public function testParsesRequestMessagesWithCustomMethod(): void
{
$req = "GET_DATA / HTTP/1.1\r\nFoo: Bar\r\nHost: foo.com\r\n\r\n";
$request = Psr7\Message::parseRequest($req);
self::assertSame('GET_DATA', $request->getMethod());
}
public function testParsesRequestMessagesWithNumericHeader(): void
{
$req = "GET /abc HTTP/1.0\r\nHost: foo.com\r\nFoo: Bar\r\nBaz: Bam\r\nBaz: Qux\r\n123: 456\r\n\r\nTest";
$request = Psr7\Message::parseRequest($req);
self::assertSame('GET', $request->getMethod());
self::assertSame('/abc', $request->getRequestTarget());
self::assertSame('1.0', $request->getProtocolVersion());
self::assertSame('foo.com', $request->getHeaderLine('Host'));
self::assertSame('Bar', $request->getHeaderLine('Foo'));
self::assertSame('Bam, Qux', $request->getHeaderLine('Baz'));
self::assertSame('456', $request->getHeaderLine('123'));
self::assertSame('Test', (string) $request->getBody());
self::assertSame('http://foo.com/abc', (string) $request->getUri());
}
public function testParsesRequestMessagesWithFoldedHeadersOnHttp10(): void
{
$req = "PUT / HTTP/1.0\r\nFoo: Bar\r\n Bam\r\n\r\n";
$request = Psr7\Message::parseRequest($req);
self::assertSame('PUT', $request->getMethod());
self::assertSame('/', $request->getRequestTarget());
self::assertSame('Bar Bam', $request->getHeaderLine('Foo'));
}
public function testRequestParsingFailsWithFoldedHeadersOnHttp11(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Invalid header syntax: Obsolete line folding');
Psr7\Message::parseResponse("GET_DATA / HTTP/1.1\r\nFoo: Bar\r\n Biz: Bam\r\n\r\n");
}
public function testParsesRequestMessagesWhenHeaderDelimiterIsOnlyALineFeed(): void
{
$req = "PUT / HTTP/1.0\nFoo: Bar\nBaz: Bam\n\n";
$request = Psr7\Message::parseRequest($req);
self::assertSame('PUT', $request->getMethod());
self::assertSame('/', $request->getRequestTarget());
self::assertSame('Bar', $request->getHeaderLine('Foo'));
self::assertSame('Bam', $request->getHeaderLine('Baz'));
}
public function testValidatesRequestMessages(): void
{
$this->expectException(\InvalidArgumentException::class);
Psr7\Message::parseRequest("HTTP/1.1 200 OK\r\n\r\n");
}
public function testParsesResponseMessages(): void
{
$res = "HTTP/1.0 200 OK\r\nFoo: Bar\r\nBaz: Bam\r\nBaz: Qux\r\n\r\nTest";
$response = Psr7\Message::parseResponse($res);
self::assertSame(200, $response->getStatusCode());
self::assertSame('OK', $response->getReasonPhrase());
self::assertSame('1.0', $response->getProtocolVersion());
self::assertSame('Bar', $response->getHeaderLine('Foo'));
self::assertSame('Bam, Qux', $response->getHeaderLine('Baz'));
self::assertSame('Test', (string) $response->getBody());
}
public function testParsesResponseWithoutReason(): void
{
$res = "HTTP/1.0 200\r\nFoo: Bar\r\nBaz: Bam\r\nBaz: Qux\r\n\r\nTest";
$response = Psr7\Message::parseResponse($res);
self::assertSame(200, $response->getStatusCode());
self::assertSame('OK', $response->getReasonPhrase());
self::assertSame('1.0', $response->getProtocolVersion());
self::assertSame('Bar', $response->getHeaderLine('Foo'));
self::assertSame('Bam, Qux', $response->getHeaderLine('Baz'));
self::assertSame('Test', (string) $response->getBody());
}
public function testParsesResponseWithLeadingDelimiter(): void
{
$res = "\r\nHTTP/1.0 200\r\nFoo: Bar\r\n\r\nTest";
$response = Psr7\Message::parseResponse($res);
self::assertSame(200, $response->getStatusCode());
self::assertSame('OK', $response->getReasonPhrase());
self::assertSame('1.0', $response->getProtocolVersion());
self::assertSame('Bar', $response->getHeaderLine('Foo'));
self::assertSame('Test', (string) $response->getBody());
}
public function testParsesResponseWithFoldedHeadersOnHttp10(): void
{
$res = "HTTP/1.0 200\r\nFoo: Bar\r\n Bam\r\n\r\nTest";
$response = Psr7\Message::parseResponse($res);
self::assertSame(200, $response->getStatusCode());
self::assertSame('OK', $response->getReasonPhrase());
self::assertSame('1.0', $response->getProtocolVersion());
self::assertSame('Bar Bam', $response->getHeaderLine('Foo'));
self::assertSame('Test', (string) $response->getBody());
}
public function testResponseParsingFailsWithFoldedHeadersOnHttp11(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Invalid header syntax: Obsolete line folding');
Psr7\Message::parseResponse("HTTP/1.1 200\r\nFoo: Bar\r\n Biz: Bam\r\nBaz: Qux\r\n\r\nTest");
}
public function testParsesResponseWhenHeaderDelimiterIsOnlyALineFeed(): void
{
$res = "HTTP/1.0 200\nFoo: Bar\nBaz: Bam\n\nTest\n\nOtherTest";
$response = Psr7\Message::parseResponse($res);
self::assertSame(200, $response->getStatusCode());
self::assertSame('OK', $response->getReasonPhrase());
self::assertSame('1.0', $response->getProtocolVersion());
self::assertSame('Bar', $response->getHeaderLine('Foo'));
self::assertSame('Bam', $response->getHeaderLine('Baz'));
self::assertSame("Test\n\nOtherTest", (string) $response->getBody());
}
public function testResponseParsingFailsWithoutHeaderDelimiter(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Invalid message: Missing header delimiter');
Psr7\Message::parseResponse("HTTP/1.0 200\r\nFoo: Bar\r\n Baz: Bam\r\nBaz: Qux\r\n");
}
public function testValidatesResponseMessages(): void
{
$this->expectException(\InvalidArgumentException::class);
Psr7\Message::parseResponse("GET / HTTP/1.1\r\n\r\n");
}
public function testMessageBodySummaryWithSmallBody(): void
{
$message = new Psr7\Response(200, [], 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.');
self::assertSame('Lorem ipsum dolor sit amet, consectetur adipiscing elit.', Psr7\Message::bodySummary($message));
}
public function testMessageBodySummaryWithLargeBody(): void
{
$message = new Psr7\Response(200, [], 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.');
self::assertSame('Lorem ipsu (truncated...)', Psr7\Message::bodySummary($message, 10));
}
public function testMessageBodySummaryWithSpecialUTF8Characters(): void
{
$message = new Psr7\Response(200, [], '’é€௵ဪ‱');
self::assertSame('’é€௵ဪ‱', Psr7\Message::bodySummary($message));
}
public function testMessageBodySummaryWithSpecialUTF8CharactersAndLargeBody(): void
{
$message = new Psr7\Response(200, [], '🤦🏾‍♀️');
// The first Unicode codepoint of the body has four bytes.
self::assertNull(Psr7\Message::bodySummary($message, 3));
}
public function testMessageBodySummaryWithEmptyBody(): void
{
$message = new Psr7\Response(200, [], '');
self::assertNull(Psr7\Message::bodySummary($message));
}
public function testMessageBodySummaryNotInitiallyRewound(): void
{
$message = new Psr7\Response(200, [], 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.');
$message->getBody()->read(10);
self::assertSame('Lorem ipsu (truncated...)', Psr7\Message::bodySummary($message, 10));
}
public function testGetResponseBodySummaryOfNonReadableStream(): void
{
$message = new Psr7\Response(500, [], new ReadSeekOnlyStream());
self::assertNull(Psr7\Message::bodySummary($message));
}
}

25
vendor/guzzlehttp/psr7/tests/MimeTypeTest.php

@ -1,25 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7;
use PHPUnit\Framework\TestCase;
class MimeTypeTest extends TestCase
{
public function testDetermineFromExtension(): void
{
self::assertNull(Psr7\MimeType::fromExtension('not-a-real-extension'));
self::assertSame('application/json', Psr7\MimeType::fromExtension('json'));
}
public function testDetermineFromFilename(): void
{
self::assertSame(
'image/jpeg',
Psr7\MimeType::fromFilename('/tmp/images/IMG034821.JPEG')
);
}
}

330
vendor/guzzlehttp/psr7/tests/MultipartStreamTest.php

@ -1,330 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\MultipartStream;
use PHPUnit\Framework\TestCase;
class MultipartStreamTest extends TestCase
{
public function testCreatesDefaultBoundary(): void
{
$b = new MultipartStream();
self::assertNotEmpty($b->getBoundary());
}
public function testCanProvideBoundary(): void
{
$b = new MultipartStream([], 'foo');
self::assertSame('foo', $b->getBoundary());
}
public function testIsNotWritable(): void
{
$b = new MultipartStream();
self::assertFalse($b->isWritable());
}
public function testCanCreateEmptyStream(): void
{
$b = new MultipartStream();
$boundary = $b->getBoundary();
self::assertSame("--{$boundary}--\r\n", $b->getContents());
self::assertSame(strlen($boundary) + 6, $b->getSize());
}
public function testValidatesFilesArrayElement(): void
{
$this->expectException(\InvalidArgumentException::class);
new MultipartStream([['foo' => 'bar']]);
}
public function testEnsuresFileHasName(): void
{
$this->expectException(\InvalidArgumentException::class);
new MultipartStream([['contents' => 'bar']]);
}
public function testSerializesFields(): void
{
$b = new MultipartStream([
[
'name' => 'foo',
'contents' => 'bar',
],
[
'name' => 'baz',
'contents' => 'bam',
],
], 'boundary');
$expected = \implode('', [
"--boundary\r\n",
"Content-Disposition: form-data; name=\"foo\"\r\n",
"Content-Length: 3\r\n",
"\r\n",
"bar\r\n",
"--boundary\r\n",
"Content-Disposition: form-data; name=\"baz\"\r\n",
"Content-Length: 3\r\n",
"\r\n",
"bam\r\n",
"--boundary--\r\n",
]);
self::assertSame($expected, (string) $b);
}
public function testSerializesNonStringFields(): void
{
$b = new MultipartStream([
[
'name' => 'int',
'contents' => (int) 1,
],
[
'name' => 'bool',
'contents' => (bool) false,
],
[
'name' => 'bool2',
'contents' => (bool) true,
],
[
'name' => 'float',
'contents' => (float) 1.1,
],
], 'boundary');
$expected = \implode('', [
"--boundary\r\n",
"Content-Disposition: form-data; name=\"int\"\r\n",
"Content-Length: 1\r\n",
"\r\n",
"1\r\n",
"--boundary\r\n",
"Content-Disposition: form-data; name=\"bool\"\r\n",
"\r\n",
"\r\n",
'--boundary',
"\r\n",
"Content-Disposition: form-data; name=\"bool2\"\r\n",
"Content-Length: 1\r\n",
"\r\n",
"1\r\n",
"--boundary\r\n",
"Content-Disposition: form-data; name=\"float\"\r\n",
"Content-Length: 3\r\n",
"\r\n",
"1.1\r\n",
"--boundary--\r\n",
'',
]);
self::assertSame($expected, (string) $b);
}
public function testSerializesFiles(): void
{
$f1 = Psr7\FnStream::decorate(Psr7\Utils::streamFor('foo'), [
'getMetadata' => static function (): string {
return '/foo/bar.txt';
},
]);
$f2 = Psr7\FnStream::decorate(Psr7\Utils::streamFor('baz'), [
'getMetadata' => static function (): string {
return '/foo/baz.jpg';
},
]);
$f3 = Psr7\FnStream::decorate(Psr7\Utils::streamFor('bar'), [
'getMetadata' => static function (): string {
return '/foo/bar.unknown';
},
]);
$b = new MultipartStream([
[
'name' => 'foo',
'contents' => $f1,
],
[
'name' => 'qux',
'contents' => $f2,
],
[
'name' => 'qux',
'contents' => $f3,
],
], 'boundary');
$expected = \implode('', [
"--boundary\r\n",
"Content-Disposition: form-data; name=\"foo\"; filename=\"bar.txt\"\r\n",
"Content-Length: 3\r\n",
"Content-Type: text/plain\r\n",
"\r\n",
"foo\r\n",
"--boundary\r\n",
"Content-Disposition: form-data; name=\"qux\"; filename=\"baz.jpg\"\r\n",
"Content-Length: 3\r\n",
"Content-Type: image/jpeg\r\n",
"\r\n",
"baz\r\n",
"--boundary\r\n",
"Content-Disposition: form-data; name=\"qux\"; filename=\"bar.unknown\"\r\n",
"Content-Length: 3\r\n",
"Content-Type: application/octet-stream\r\n",
"\r\n",
"bar\r\n",
"--boundary--\r\n",
]);
self::assertSame($expected, (string) $b);
}
public function testSerializesFilesWithMixedNewlines(): void
{
$content = "LF\nCRLF\r\nCR\r";
$contentLength = \strlen($content);
$f1 = Psr7\FnStream::decorate(Psr7\Utils::streamFor($content), [
'getMetadata' => static function (): string {
return '/foo/newlines.txt';
},
]);
$b = new MultipartStream([
[
'name' => 'newlines',
'contents' => $f1,
],
], 'boundary');
$expected = \implode('', [
"--boundary\r\n",
"Content-Disposition: form-data; name=\"newlines\"; filename=\"newlines.txt\"\r\n",
"Content-Length: {$contentLength}\r\n",
"Content-Type: text/plain\r\n",
"\r\n",
"{$content}\r\n",
"--boundary--\r\n",
]);
// Do not perform newline normalization in the assertion! The `$content` must
// be embedded as-is in the payload.
self::assertSame($expected, (string) $b);
}
public function testSerializesFilesWithCustomHeaders(): void
{
$f1 = Psr7\FnStream::decorate(Psr7\Utils::streamFor('foo'), [
'getMetadata' => static function (): string {
return '/foo/bar.txt';
},
]);
$b = new MultipartStream([
[
'name' => 'foo',
'contents' => $f1,
'headers' => [
'x-foo' => 'bar',
'content-disposition' => 'custom',
],
],
], 'boundary');
$expected = \implode('', [
"--boundary\r\n",
"x-foo: bar\r\n",
"content-disposition: custom\r\n",
"Content-Length: 3\r\n",
"Content-Type: text/plain\r\n",
"\r\n",
"foo\r\n",
"--boundary--\r\n",
]);
self::assertSame($expected, (string) $b);
}
public function testSerializesFilesWithCustomHeadersAndMultipleValues(): void
{
$f1 = Psr7\FnStream::decorate(Psr7\Utils::streamFor('foo'), [
'getMetadata' => static function (): string {
return '/foo/bar.txt';
},
]);
$f2 = Psr7\FnStream::decorate(Psr7\Utils::streamFor('baz'), [
'getMetadata' => static function (): string {
return '/foo/baz.jpg';
},
]);
$b = new MultipartStream([
[
'name' => 'foo',
'contents' => $f1,
'headers' => [
'x-foo' => 'bar',
'content-disposition' => 'custom',
],
],
[
'name' => 'foo',
'contents' => $f2,
'headers' => ['cOntenT-Type' => 'custom'],
],
], 'boundary');
$expected = \implode('', [
"--boundary\r\n",
"x-foo: bar\r\n",
"content-disposition: custom\r\n",
"Content-Length: 3\r\n",
"Content-Type: text/plain\r\n",
"\r\n",
"foo\r\n",
"--boundary\r\n",
"cOntenT-Type: custom\r\n",
"Content-Disposition: form-data; name=\"foo\"; filename=\"baz.jpg\"\r\n",
"Content-Length: 3\r\n",
"\r\n",
"baz\r\n",
"--boundary--\r\n",
]);
self::assertSame($expected, (string) $b);
}
public function testCanCreateWithNoneMetadataStreamField(): void
{
$str = 'dummy text';
$a = Psr7\Utils::streamFor(static function () use ($str): string {
return $str;
});
$b = new Psr7\LimitStream($a, \strlen($str));
$c = new MultipartStream([
[
'name' => 'foo',
'contents' => $b,
],
], 'boundary');
$expected = \implode('', [
"--boundary\r\n",
"Content-Disposition: form-data; name=\"foo\"\r\n",
"\r\n",
$str."\r\n",
"--boundary--\r\n",
]);
self::assertSame($expected, (string) $c);
}
}

38
vendor/guzzlehttp/psr7/tests/NoSeekStreamTest.php

@ -1,38 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7\NoSeekStream;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\StreamInterface;
/**
* @covers \GuzzleHttp\Psr7\NoSeekStream
* @covers \GuzzleHttp\Psr7\StreamDecoratorTrait
*/
class NoSeekStreamTest extends TestCase
{
public function testCannotSeek(): void
{
$s = $this->createMock(StreamInterface::class);
$s->expects(self::never())->method('seek');
$s->expects(self::never())->method('isSeekable');
$wrapped = new NoSeekStream($s);
self::assertFalse($wrapped->isSeekable());
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('Cannot seek a NoSeekStream');
$wrapped->seek(2);
}
public function testToStringDoesNotSeek(): void
{
$s = \GuzzleHttp\Psr7\Utils::streamFor('foo');
$s->seek(1);
$wrapped = new NoSeekStream($s);
self::assertSame('oo', (string) $wrapped);
$wrapped->close();
}
}

105
vendor/guzzlehttp/psr7/tests/PumpStreamTest.php

@ -1,105 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\LimitStream;
use GuzzleHttp\Psr7\PumpStream;
use PHPUnit\Framework\TestCase;
class PumpStreamTest extends TestCase
{
public function testHasMetadataAndSize(): void
{
$p = new PumpStream(function (): void {
}, [
'metadata' => ['foo' => 'bar'],
'size' => 100,
]);
self::assertSame('bar', $p->getMetadata('foo'));
self::assertSame(['foo' => 'bar'], $p->getMetadata());
self::assertSame(100, $p->getSize());
}
public function testCanReadFromCallable(): void
{
$p = Psr7\Utils::streamFor(function ($size) {
return 'a';
});
self::assertSame('a', $p->read(1));
self::assertSame(1, $p->tell());
self::assertSame('aaaaa', $p->read(5));
self::assertSame(6, $p->tell());
}
public function testStoresExcessDataInBuffer(): void
{
$called = [];
$p = Psr7\Utils::streamFor(function ($size) use (&$called) {
$called[] = $size;
return 'abcdef';
});
self::assertSame('a', $p->read(1));
self::assertSame('b', $p->read(1));
self::assertSame('cdef', $p->read(4));
self::assertSame('abcdefabc', $p->read(9));
self::assertSame([1, 9, 3], $called);
}
public function testInifiniteStreamWrappedInLimitStream(): void
{
$p = Psr7\Utils::streamFor(function () {
return 'a';
});
$s = new LimitStream($p, 5);
self::assertSame('aaaaa', (string) $s);
}
public function testDescribesCapabilities(): void
{
$p = Psr7\Utils::streamFor(function (): void {
});
self::assertTrue($p->isReadable());
self::assertFalse($p->isSeekable());
self::assertFalse($p->isWritable());
self::assertNull($p->getSize());
self::assertSame('', $p->getContents());
self::assertSame('', (string) $p);
$p->close();
self::assertSame('', $p->read(10));
self::assertTrue($p->eof());
try {
self::assertFalse($p->write('aa'));
self::fail();
} catch (\RuntimeException $e) {
}
}
/**
* @requires PHP < 7.4
*/
public function testThatConvertingStreamToStringWillTriggerErrorAndWillReturnEmptyString(): void
{
$p = Psr7\Utils::streamFor(function ($size): void {
throw new \Exception();
});
self::assertInstanceOf(PumpStream::class, $p);
$errors = [];
set_error_handler(function (int $errorNumber, string $errorMessage) use (&$errors): void {
$errors[] = ['number' => $errorNumber, 'message' => $errorMessage];
});
(string) $p;
restore_error_handler();
self::assertCount(1, $errors);
self::assertSame(E_USER_ERROR, $errors[0]['number']);
self::assertStringStartsWith('GuzzleHttp\Psr7\PumpStream::__toString exception:', $errors[0]['message']);
}
}

124
vendor/guzzlehttp/psr7/tests/QueryTest.php

@ -1,124 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7;
use PHPUnit\Framework\TestCase;
class QueryTest extends TestCase
{
public function parseQueryProvider()
{
return [
// Does not need to parse when the string is empty
['', []],
// Can parse mult-values items
['q=a&q=b', ['q' => ['a', 'b']]],
// Can parse multi-valued items that use numeric indices
['q[0]=a&q[1]=b', ['q[0]' => 'a', 'q[1]' => 'b']],
// Can parse duplicates and does not include numeric indices
['q[]=a&q[]=b', ['q[]' => ['a', 'b']]],
// Ensures that the value of "q" is an array even though one value
['q[]=a', ['q[]' => 'a']],
// Does not modify "." to "_" like PHP's parse_str()
['q.a=a&q.b=b', ['q.a' => 'a', 'q.b' => 'b']],
// Can decode %20 to " "
['q%20a=a%20b', ['q a' => 'a b']],
// Can parse funky strings with no values by assigning each to null
['q&a', ['q' => null, 'a' => null]],
// Does not strip trailing equal signs
['data=abc=', ['data' => 'abc=']],
// Can store duplicates without affecting other values
['foo=a&foo=b&?µ=c', ['foo' => ['a', 'b'], '?µ' => 'c']],
// Sets value to null when no "=" is present
['foo', ['foo' => null]],
// Preserves "0" keys.
['0', ['0' => null]],
// Sets the value to an empty string when "=" is present
['0=', ['0' => '']],
// Preserves falsey keys
['var=0', ['var' => '0']],
['a[b][c]=1&a[b][c]=2', ['a[b][c]' => ['1', '2']]],
['a[b]=c&a[d]=e', ['a[b]' => 'c', 'a[d]' => 'e']],
// Ensure it doesn't leave things behind with repeated values
// Can parse mult-values items
['q=a&q=b&q=c', ['q' => ['a', 'b', 'c']]],
// Keeps first null when parsing mult-values
['q&q=&q=a', ['q' => [null, '', 'a']]],
];
}
/**
* @dataProvider parseQueryProvider
*/
public function testParsesQueries($input, $output): void
{
$result = Psr7\Query::parse($input);
self::assertSame($output, $result);
}
public function testDoesNotDecode(): void
{
$str = 'foo%20=bar';
$data = Psr7\Query::parse($str, false);
self::assertSame(['foo%20' => 'bar'], $data);
}
/**
* @dataProvider parseQueryProvider
*/
public function testParsesAndBuildsQueries($input): void
{
$result = Psr7\Query::parse($input, false);
self::assertSame($input, Psr7\Query::build($result, false));
}
public function testEncodesWithRfc1738(): void
{
$str = Psr7\Query::build(['foo bar' => 'baz+'], PHP_QUERY_RFC1738);
self::assertSame('foo+bar=baz%2B', $str);
}
public function testEncodesWithRfc3986(): void
{
$str = Psr7\Query::build(['foo bar' => 'baz+'], PHP_QUERY_RFC3986);
self::assertSame('foo%20bar=baz%2B', $str);
}
public function testDoesNotEncode(): void
{
$str = Psr7\Query::build(['foo bar' => 'baz+'], false);
self::assertSame('foo bar=baz+', $str);
}
public function testCanControlDecodingType(): void
{
$result = Psr7\Query::parse('var=foo+bar', PHP_QUERY_RFC3986);
self::assertSame('foo+bar', $result['var']);
$result = Psr7\Query::parse('var=foo+bar', PHP_QUERY_RFC1738);
self::assertSame('foo bar', $result['var']);
}
public function testBuildBooleans(): void
{
$data = [
'true' => true,
'false' => false,
];
self::assertEquals(http_build_query($data), Psr7\Query::build($data));
$data = [
'foo' => [true, 'true'],
'bar' => [false, 'false'],
];
self::assertEquals('foo=1&foo=true&bar=0&bar=false', Psr7\Query::build($data, PHP_QUERY_RFC1738));
$data = [
'foo' => true,
'bar' => false,
];
self::assertEquals('foo=true&bar=false', Psr7\Query::build($data, PHP_QUERY_RFC3986, false));
}
}

26
vendor/guzzlehttp/psr7/tests/ReadSeekOnlyStream.php

@ -1,26 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7\Stream;
use GuzzleHttp\Psr7\Utils;
final class ReadSeekOnlyStream extends Stream
{
public function __construct()
{
parent::__construct(Utils::tryFopen('php://memory', 'wb'));
}
public function isSeekable(): bool
{
return true;
}
public function isReadable(): bool
{
return false;
}
}

362
vendor/guzzlehttp/psr7/tests/RequestTest.php

@ -1,362 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Uri;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\StreamInterface;
/**
* @covers \GuzzleHttp\Psr7\MessageTrait
* @covers \GuzzleHttp\Psr7\Request
*/
class RequestTest extends TestCase
{
public function testRequestUriMayBeString(): void
{
$r = new Request('GET', '/');
self::assertSame('/', (string) $r->getUri());
}
public function testRequestUriMayBeUri(): void
{
$uri = new Uri('/');
$r = new Request('GET', $uri);
self::assertSame($uri, $r->getUri());
}
public function testValidateRequestUri(): void
{
$this->expectException(\InvalidArgumentException::class);
new Request('GET', '///');
}
public function testCanConstructWithBody(): void
{
$r = new Request('GET', '/', [], 'baz');
self::assertInstanceOf(StreamInterface::class, $r->getBody());
self::assertSame('baz', (string) $r->getBody());
}
public function testNullBody(): void
{
$r = new Request('GET', '/', [], null);
self::assertInstanceOf(StreamInterface::class, $r->getBody());
self::assertSame('', (string) $r->getBody());
}
public function testFalseyBody(): void
{
$r = new Request('GET', '/', [], '0');
self::assertInstanceOf(StreamInterface::class, $r->getBody());
self::assertSame('0', (string) $r->getBody());
}
public function testConstructorDoesNotReadStreamBody(): void
{
$streamIsRead = false;
$body = Psr7\FnStream::decorate(Psr7\Utils::streamFor(''), [
'__toString' => function () use (&$streamIsRead) {
$streamIsRead = true;
return '';
},
]);
$r = new Request('GET', '/', [], $body);
self::assertFalse($streamIsRead);
self::assertSame($body, $r->getBody());
}
public function testCapitalizesMethod(): void
{
$r = new Request('get', '/');
self::assertSame('GET', $r->getMethod());
}
public function testCapitalizesWithMethod(): void
{
$r = new Request('GET', '/');
self::assertSame('PUT', $r->withMethod('put')->getMethod());
}
public function testWithUri(): void
{
$r1 = new Request('GET', '/');
$u1 = $r1->getUri();
$u2 = new Uri('http://www.example.com');
$r2 = $r1->withUri($u2);
self::assertNotSame($r1, $r2);
self::assertSame($u2, $r2->getUri());
self::assertSame($u1, $r1->getUri());
}
/**
* @dataProvider invalidMethodsProvider
*/
public function testConstructWithInvalidMethods($method): void
{
$this->expectException(\TypeError::class);
new Request($method, '/');
}
/**
* @dataProvider invalidMethodsProvider
*/
public function testWithInvalidMethods($method): void
{
$r = new Request('get', '/');
$this->expectException(\InvalidArgumentException::class);
$r->withMethod($method);
}
public function invalidMethodsProvider(): iterable
{
return [
[null],
[false],
[['foo']],
[new \stdClass()],
];
}
public function testSameInstanceWhenSameUri(): void
{
$r1 = new Request('GET', 'http://foo.com');
$r2 = $r1->withUri($r1->getUri());
self::assertSame($r1, $r2);
}
public function testWithRequestTarget(): void
{
$r1 = new Request('GET', '/');
$r2 = $r1->withRequestTarget('*');
self::assertSame('*', $r2->getRequestTarget());
self::assertSame('/', $r1->getRequestTarget());
}
public function testRequestTargetDoesNotAllowSpaces(): void
{
$r1 = new Request('GET', '/');
$this->expectException(\InvalidArgumentException::class);
$r1->withRequestTarget('/foo bar');
}
public function testRequestTargetDefaultsToSlash(): void
{
$r1 = new Request('GET', '');
self::assertSame('/', $r1->getRequestTarget());
$r2 = new Request('GET', '*');
self::assertSame('*', $r2->getRequestTarget());
$r3 = new Request('GET', 'http://foo.com/bar baz/');
self::assertSame('/bar%20baz/', $r3->getRequestTarget());
}
public function testBuildsRequestTarget(): void
{
$r1 = new Request('GET', 'http://foo.com/baz?bar=bam');
self::assertSame('/baz?bar=bam', $r1->getRequestTarget());
}
public function testBuildsRequestTargetWithFalseyQuery(): void
{
$r1 = new Request('GET', 'http://foo.com/baz?0');
self::assertSame('/baz?0', $r1->getRequestTarget());
}
public function testHostIsAddedFirst(): void
{
$r = new Request('GET', 'http://foo.com/baz?bar=bam', ['Foo' => 'Bar']);
self::assertSame([
'Host' => ['foo.com'],
'Foo' => ['Bar'],
], $r->getHeaders());
}
public function testHeaderValueWithWhitespace(): void
{
$r = new Request('GET', 'https://example.com/', [
'User-Agent' => 'Linux f0f489981e90 5.10.104-linuxkit 1 SMP Wed Mar 9 19:05:23 UTC 2022 x86_64',
]);
self::assertSame([
'Host' => ['example.com'],
'User-Agent' => ['Linux f0f489981e90 5.10.104-linuxkit 1 SMP Wed Mar 9 19:05:23 UTC 2022 x86_64'],
], $r->getHeaders());
}
public function testCanGetHeaderAsCsv(): void
{
$r = new Request('GET', 'http://foo.com/baz?bar=bam', [
'Foo' => ['a', 'b', 'c'],
]);
self::assertSame('a, b, c', $r->getHeaderLine('Foo'));
self::assertSame('', $r->getHeaderLine('Bar'));
}
/**
* @dataProvider provideHeadersContainingNotAllowedChars
*/
public function testContainsNotAllowedCharsOnHeaderField($header): void
{
$this->expectExceptionMessage(
sprintf(
'"%s" is not valid header name',
$header
)
);
$r = new Request(
'GET',
'http://foo.com/baz?bar=bam',
[
$header => 'value',
]
);
}
public function provideHeadersContainingNotAllowedChars(): iterable
{
return [[' key '], ['key '], [' key'], ['key/'], ['key('], ['key\\'], [' ']];
}
/**
* @dataProvider provideHeadersContainsAllowedChar
*/
public function testContainsAllowedCharsOnHeaderField($header): void
{
$r = new Request(
'GET',
'http://foo.com/baz?bar=bam',
[
$header => 'value',
]
);
self::assertArrayHasKey($header, $r->getHeaders());
}
public function provideHeadersContainsAllowedChar(): iterable
{
return [
['key'],
['key#'],
['key$'],
['key%'],
['key&'],
['key*'],
['key+'],
['key.'],
['key^'],
['key_'],
['key|'],
['key~'],
['key!'],
['key-'],
["key'"],
['key`'],
];
}
public function testHostIsNotOverwrittenWhenPreservingHost(): void
{
$r = new Request('GET', 'http://foo.com/baz?bar=bam', ['Host' => 'a.com']);
self::assertSame(['Host' => ['a.com']], $r->getHeaders());
$r2 = $r->withUri(new Uri('http://www.foo.com/bar'), true);
self::assertSame('a.com', $r2->getHeaderLine('Host'));
}
public function testWithUriSetsHostIfNotSet(): void
{
$r = (new Request('GET', 'http://foo.com/baz?bar=bam'))->withoutHeader('Host');
self::assertSame([], $r->getHeaders());
$r2 = $r->withUri(new Uri('http://www.baz.com/bar'), true);
self::assertSame('www.baz.com', $r2->getHeaderLine('Host'));
}
public function testOverridesHostWithUri(): void
{
$r = new Request('GET', 'http://foo.com/baz?bar=bam');
self::assertSame(['Host' => ['foo.com']], $r->getHeaders());
$r2 = $r->withUri(new Uri('http://www.baz.com/bar'));
self::assertSame('www.baz.com', $r2->getHeaderLine('Host'));
}
public function testAggregatesHeaders(): void
{
$r = new Request('GET', '', [
'ZOO' => 'zoobar',
'zoo' => ['foobar', 'zoobar'],
]);
self::assertSame(['ZOO' => ['zoobar', 'foobar', 'zoobar']], $r->getHeaders());
self::assertSame('zoobar, foobar, zoobar', $r->getHeaderLine('zoo'));
}
public function testAddsPortToHeader(): void
{
$r = new Request('GET', 'http://foo.com:8124/bar');
self::assertSame('foo.com:8124', $r->getHeaderLine('host'));
}
public function testAddsPortToHeaderAndReplacePreviousPort(): void
{
$r = new Request('GET', 'http://foo.com:8124/bar');
$r = $r->withUri(new Uri('http://foo.com:8125/bar'));
self::assertSame('foo.com:8125', $r->getHeaderLine('host'));
}
/**
* @dataProvider provideHeaderValuesContainingNotAllowedChars
*/
public function testContainsNotAllowedCharsOnHeaderValue(string $value): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage(sprintf('"%s" is not valid header value', $value));
$r = new Request(
'GET',
'http://foo.com/baz?bar=bam',
[
'testing' => $value,
]
);
}
public function provideHeaderValuesContainingNotAllowedChars(): iterable
{
// Explicit tests for newlines as the most common exploit vector.
$tests = [
["new\nline"],
["new\r\nline"],
["new\rline"],
// Line folding is technically allowed, but deprecated.
// We don't support it.
["new\r\n line"],
["newline\n"],
["\nnewline"],
["newline\r\n"],
["\r\nnewline"],
];
for ($i = 0; $i <= 0xFF; ++$i) {
if (\chr($i) == "\t") {
continue;
}
if (\chr($i) == ' ') {
continue;
}
if ($i >= 0x21 && $i <= 0x7E) {
continue;
}
if ($i >= 0x80) {
continue;
}
$tests[] = ['foo'.\chr($i).'bar'];
$tests[] = ['foo'.\chr($i)];
}
return $tests;
}
}

391
vendor/guzzlehttp/psr7/tests/ResponseTest.php

@ -1,391 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\Response;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\StreamInterface;
/**
* @covers \GuzzleHttp\Psr7\MessageTrait
* @covers \GuzzleHttp\Psr7\Response
*/
class ResponseTest extends TestCase
{
public function testDefaultConstructor(): void
{
$r = new Response();
self::assertSame(200, $r->getStatusCode());
self::assertSame('1.1', $r->getProtocolVersion());
self::assertSame('OK', $r->getReasonPhrase());
self::assertSame([], $r->getHeaders());
self::assertInstanceOf(StreamInterface::class, $r->getBody());
self::assertSame('', (string) $r->getBody());
}
public function testCanConstructWithStatusCode(): void
{
$r = new Response(404);
self::assertSame(404, $r->getStatusCode());
self::assertSame('Not Found', $r->getReasonPhrase());
}
public function testConstructorDoesNotReadStreamBody(): void
{
$streamIsRead = false;
$body = Psr7\FnStream::decorate(Psr7\Utils::streamFor(''), [
'__toString' => function () use (&$streamIsRead) {
$streamIsRead = true;
return '';
},
]);
$r = new Response(200, [], $body);
self::assertFalse($streamIsRead);
self::assertSame($body, $r->getBody());
}
public function testStatusCanBeNumericString(): void
{
$r = (new Response())->withStatus('201');
self::assertSame(201, $r->getStatusCode());
self::assertSame('Created', $r->getReasonPhrase());
}
public function testCanConstructWithHeaders(): void
{
$r = new Response(200, ['Foo' => 'Bar']);
self::assertSame(['Foo' => ['Bar']], $r->getHeaders());
self::assertSame('Bar', $r->getHeaderLine('Foo'));
self::assertSame(['Bar'], $r->getHeader('Foo'));
}
public function testCanConstructWithHeadersAsArray(): void
{
$r = new Response(200, [
'Foo' => ['baz', 'bar'],
]);
self::assertSame(['Foo' => ['baz', 'bar']], $r->getHeaders());
self::assertSame('baz, bar', $r->getHeaderLine('Foo'));
self::assertSame(['baz', 'bar'], $r->getHeader('Foo'));
}
public function testCanConstructWithBody(): void
{
$r = new Response(200, [], 'baz');
self::assertInstanceOf(StreamInterface::class, $r->getBody());
self::assertSame('baz', (string) $r->getBody());
}
public function testNullBody(): void
{
$r = new Response(200, [], null);
self::assertInstanceOf(StreamInterface::class, $r->getBody());
self::assertSame('', (string) $r->getBody());
}
public function testFalseyBody(): void
{
$r = new Response(200, [], '0');
self::assertInstanceOf(StreamInterface::class, $r->getBody());
self::assertSame('0', (string) $r->getBody());
}
public function testCanConstructWithReason(): void
{
$r = new Response(200, [], null, '1.1', 'bar');
self::assertSame('bar', $r->getReasonPhrase());
$r = new Response(200, [], null, '1.1', '0');
self::assertSame('0', $r->getReasonPhrase(), 'Falsey reason works');
}
public function testCanConstructWithProtocolVersion(): void
{
$r = new Response(200, [], null, '1000');
self::assertSame('1000', $r->getProtocolVersion());
}
public function testWithStatusCodeAndNoReason(): void
{
$r = (new Response())->withStatus(201);
self::assertSame(201, $r->getStatusCode());
self::assertSame('Created', $r->getReasonPhrase());
}
public function testWithStatusCodeAndReason(): void
{
$r = (new Response())->withStatus(201, 'Foo');
self::assertSame(201, $r->getStatusCode());
self::assertSame('Foo', $r->getReasonPhrase());
$r = (new Response())->withStatus(201, '0');
self::assertSame(201, $r->getStatusCode());
self::assertSame('0', $r->getReasonPhrase(), 'Falsey reason works');
}
public function testWithProtocolVersion(): void
{
$r = (new Response())->withProtocolVersion('1000');
self::assertSame('1000', $r->getProtocolVersion());
}
public function testSameInstanceWhenSameProtocol(): void
{
$r = new Response();
self::assertSame($r, $r->withProtocolVersion('1.1'));
}
public function testWithBody(): void
{
$b = Psr7\Utils::streamFor('0');
$r = (new Response())->withBody($b);
self::assertInstanceOf(StreamInterface::class, $r->getBody());
self::assertSame('0', (string) $r->getBody());
}
public function testSameInstanceWhenSameBody(): void
{
$r = new Response();
$b = $r->getBody();
self::assertSame($r, $r->withBody($b));
}
public function testWithHeader(): void
{
$r = new Response(200, ['Foo' => 'Bar']);
$r2 = $r->withHeader('baZ', 'Bam');
self::assertSame(['Foo' => ['Bar']], $r->getHeaders());
self::assertSame(['Foo' => ['Bar'], 'baZ' => ['Bam']], $r2->getHeaders());
self::assertSame('Bam', $r2->getHeaderLine('baz'));
self::assertSame(['Bam'], $r2->getHeader('baz'));
}
public function testNumericHeaderValue(): void
{
$r = (new Response())->withHeader('Api-Version', 1);
self::assertSame(['Api-Version' => ['1']], $r->getHeaders());
}
public function testWithHeaderAsArray(): void
{
$r = new Response(200, ['Foo' => 'Bar']);
$r2 = $r->withHeader('baZ', ['Bam', 'Bar']);
self::assertSame(['Foo' => ['Bar']], $r->getHeaders());
self::assertSame(['Foo' => ['Bar'], 'baZ' => ['Bam', 'Bar']], $r2->getHeaders());
self::assertSame('Bam, Bar', $r2->getHeaderLine('baz'));
self::assertSame(['Bam', 'Bar'], $r2->getHeader('baz'));
}
public function testWithHeaderReplacesDifferentCase(): void
{
$r = new Response(200, ['Foo' => 'Bar']);
$r2 = $r->withHeader('foO', 'Bam');
self::assertSame(['Foo' => ['Bar']], $r->getHeaders());
self::assertSame(['foO' => ['Bam']], $r2->getHeaders());
self::assertSame('Bam', $r2->getHeaderLine('foo'));
self::assertSame(['Bam'], $r2->getHeader('foo'));
}
public function testWithAddedHeader(): void
{
$r = new Response(200, ['Foo' => 'Bar']);
$r2 = $r->withAddedHeader('foO', 'Baz');
self::assertSame(['Foo' => ['Bar']], $r->getHeaders());
self::assertSame(['Foo' => ['Bar', 'Baz']], $r2->getHeaders());
self::assertSame('Bar, Baz', $r2->getHeaderLine('foo'));
self::assertSame(['Bar', 'Baz'], $r2->getHeader('foo'));
}
public function testWithAddedHeaderAsArray(): void
{
$r = new Response(200, ['Foo' => 'Bar']);
$r2 = $r->withAddedHeader('foO', ['Baz', 'Bam']);
self::assertSame(['Foo' => ['Bar']], $r->getHeaders());
self::assertSame(['Foo' => ['Bar', 'Baz', 'Bam']], $r2->getHeaders());
self::assertSame('Bar, Baz, Bam', $r2->getHeaderLine('foo'));
self::assertSame(['Bar', 'Baz', 'Bam'], $r2->getHeader('foo'));
}
public function testWithAddedHeaderThatDoesNotExist(): void
{
$r = new Response(200, ['Foo' => 'Bar']);
$r2 = $r->withAddedHeader('nEw', 'Baz');
self::assertSame(['Foo' => ['Bar']], $r->getHeaders());
self::assertSame(['Foo' => ['Bar'], 'nEw' => ['Baz']], $r2->getHeaders());
self::assertSame('Baz', $r2->getHeaderLine('new'));
self::assertSame(['Baz'], $r2->getHeader('new'));
}
public function testWithoutHeaderThatExists(): void
{
$r = new Response(200, ['Foo' => 'Bar', 'Baz' => 'Bam']);
$r2 = $r->withoutHeader('foO');
self::assertTrue($r->hasHeader('foo'));
self::assertSame(['Foo' => ['Bar'], 'Baz' => ['Bam']], $r->getHeaders());
self::assertFalse($r2->hasHeader('foo'));
self::assertSame(['Baz' => ['Bam']], $r2->getHeaders());
}
public function testWithoutHeaderThatDoesNotExist(): void
{
$r = new Response(200, ['Baz' => 'Bam']);
$r2 = $r->withoutHeader('foO');
self::assertSame($r, $r2);
self::assertFalse($r2->hasHeader('foo'));
self::assertSame(['Baz' => ['Bam']], $r2->getHeaders());
}
public function testSameInstanceWhenRemovingMissingHeader(): void
{
$r = new Response();
self::assertSame($r, $r->withoutHeader('foo'));
}
public function testPassNumericHeaderNameInConstructor(): void
{
$r = new Response(200, ['Location' => 'foo', '123' => 'bar']);
self::assertSame('bar', $r->getHeaderLine('123'));
}
/**
* @dataProvider invalidHeaderProvider
*/
public function testConstructResponseInvalidHeader($header, $headerValue, $expectedMessage): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage($expectedMessage);
new Response(200, [$header => $headerValue]);
}
public function invalidHeaderProvider(): iterable
{
return [
['foo', [], 'Header value can not be an empty array.'],
['', '', '"" is not valid header name'],
['foo', new \stdClass(), 'Header value must be scalar or null but stdClass provided.'],
];
}
/**
* @dataProvider invalidWithHeaderProvider
*/
public function testWithInvalidHeader($header, $headerValue, $expectedMessage): void
{
$r = new Response();
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage($expectedMessage);
$r->withHeader($header, $headerValue);
}
public function invalidWithHeaderProvider(): iterable
{
yield from $this->invalidHeaderProvider();
yield [[], 'foo', 'Header name must be a string but array provided.'];
yield [false, 'foo', 'Header name must be a string but boolean provided.'];
yield [new \stdClass(), 'foo', 'Header name must be a string but stdClass provided.'];
yield ['', 'foo', '"" is not valid header name.'];
yield ["Content-Type\r\n\r\n", 'foo', "\"Content-Type\r\n\r\n\" is not valid header name."];
yield ["Content-Type\r\n", 'foo', "\"Content-Type\r\n\" is not valid header name."];
yield ["Content-Type\n", 'foo', "\"Content-Type\n\" is not valid header name."];
yield ["\r\nContent-Type", 'foo', "\"\r\nContent-Type\" is not valid header name."];
yield ["\nContent-Type", 'foo', "\"\nContent-Type\" is not valid header name."];
yield ["\n", 'foo', "\"\n\" is not valid header name."];
yield ["\r\n", 'foo', "\"\r\n\" is not valid header name."];
yield ["\t", 'foo', "\"\t\" is not valid header name."];
}
public function testHeaderValuesAreTrimmed(): void
{
$r1 = new Response(200, ['OWS' => " \t \tFoo\t \t "]);
$r2 = (new Response())->withHeader('OWS', " \t \tFoo\t \t ");
$r3 = (new Response())->withAddedHeader('OWS', " \t \tFoo\t \t ");
foreach ([$r1, $r2, $r3] as $r) {
self::assertSame(['OWS' => ['Foo']], $r->getHeaders());
self::assertSame('Foo', $r->getHeaderLine('OWS'));
self::assertSame(['Foo'], $r->getHeader('OWS'));
}
}
public function testWithAddedHeaderArrayValueAndKeys(): void
{
$message = (new Response())->withAddedHeader('list', ['foo' => 'one']);
$message = $message->withAddedHeader('list', ['foo' => 'two', 'bar' => 'three']);
$headerLine = $message->getHeaderLine('list');
self::assertSame('one, two, three', $headerLine);
}
/**
* @dataProvider nonIntegerStatusCodeProvider
*
* @param mixed $invalidValues
*/
public function testConstructResponseWithNonIntegerStatusCode($invalidValues): void
{
$this->expectException(\TypeError::class);
new Response($invalidValues);
}
/**
* @dataProvider nonIntegerStatusCodeProvider
*
* @param mixed $invalidValues
*/
public function testResponseChangeStatusCodeWithNonInteger($invalidValues): void
{
$response = new Response();
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Status code must be an integer value.');
$response->withStatus($invalidValues);
}
public function nonIntegerStatusCodeProvider(): iterable
{
return [
['whatever'],
['1.01'],
[1.01],
[new \stdClass()],
];
}
/**
* @dataProvider invalidStatusCodeRangeProvider
*
* @param mixed $invalidValues
*/
public function testConstructResponseWithInvalidRangeStatusCode($invalidValues): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Status code must be an integer value between 1xx and 5xx.');
new Response($invalidValues);
}
/**
* @dataProvider invalidStatusCodeRangeProvider
*
* @param mixed $invalidValues
*/
public function testResponseChangeStatusCodeWithWithInvalidRange($invalidValues): void
{
$response = new Response();
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Status code must be an integer value between 1xx and 5xx.');
$response->withStatus($invalidValues);
}
public function invalidStatusCodeRangeProvider(): iterable
{
return [
[600],
[99],
];
}
}

566
vendor/guzzlehttp/psr7/tests/ServerRequestTest.php

@ -1,566 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7\ServerRequest;
use GuzzleHttp\Psr7\UploadedFile;
use GuzzleHttp\Psr7\Uri;
use PHPUnit\Framework\TestCase;
/**
* @covers \GuzzleHttp\Psr7\ServerRequest
*/
class ServerRequestTest extends TestCase
{
public function dataNormalizeFiles(): iterable
{
return [
'Single file' => [
[
'file' => [
'name' => 'MyFile.txt',
'type' => 'text/plain',
'tmp_name' => '/tmp/php/php1h4j1o',
'error' => '0',
'size' => '123',
],
],
[
'file' => new UploadedFile(
'/tmp/php/php1h4j1o',
123,
UPLOAD_ERR_OK,
'MyFile.txt',
'text/plain'
),
],
],
'Empty file' => [
[
'image_file' => [
'name' => '',
'type' => '',
'tmp_name' => '',
'error' => '4',
'size' => '0',
],
],
[
'image_file' => new UploadedFile(
'',
0,
UPLOAD_ERR_NO_FILE,
'',
''
),
],
],
'Already Converted' => [
[
'file' => new UploadedFile(
'/tmp/php/php1h4j1o',
123,
UPLOAD_ERR_OK,
'MyFile.txt',
'text/plain'
),
],
[
'file' => new UploadedFile(
'/tmp/php/php1h4j1o',
123,
UPLOAD_ERR_OK,
'MyFile.txt',
'text/plain'
),
],
],
'Already Converted array' => [
[
'file' => [
new UploadedFile(
'/tmp/php/php1h4j1o',
123,
UPLOAD_ERR_OK,
'MyFile.txt',
'text/plain'
),
new UploadedFile(
'',
0,
UPLOAD_ERR_NO_FILE,
'',
''
),
],
],
[
'file' => [
new UploadedFile(
'/tmp/php/php1h4j1o',
123,
UPLOAD_ERR_OK,
'MyFile.txt',
'text/plain'
),
new UploadedFile(
'',
0,
UPLOAD_ERR_NO_FILE,
'',
''
),
],
],
],
'Multiple files' => [
[
'text_file' => [
'name' => 'MyFile.txt',
'type' => 'text/plain',
'tmp_name' => '/tmp/php/php1h4j1o',
'error' => '0',
'size' => '123',
],
'image_file' => [
'name' => '',
'type' => '',
'tmp_name' => '',
'error' => '4',
'size' => '0',
],
],
[
'text_file' => new UploadedFile(
'/tmp/php/php1h4j1o',
123,
UPLOAD_ERR_OK,
'MyFile.txt',
'text/plain'
),
'image_file' => new UploadedFile(
'',
0,
UPLOAD_ERR_NO_FILE,
'',
''
),
],
],
'Nested files' => [
[
'file' => [
'name' => [
0 => 'MyFile.txt',
1 => 'Image.png',
],
'type' => [
0 => 'text/plain',
1 => 'image/png',
],
'tmp_name' => [
0 => '/tmp/php/hp9hskjhf',
1 => '/tmp/php/php1h4j1o',
2 => '/tmp/php/w0ensl4ar',
],
'error' => [
0 => '0',
1 => '0',
],
'size' => [
0 => '123',
1 => '7349',
],
],
'minimum_data' => [
'tmp_name' => [
0 => '/tmp/php/hp9hskjhf',
],
],
'nested' => [
'name' => [
'other' => 'Flag.txt',
'test' => [
0 => 'Stuff.txt',
1 => '',
],
],
'type' => [
'other' => 'text/plain',
'test' => [
0 => 'text/plain',
1 => '',
],
],
'tmp_name' => [
'other' => '/tmp/php/hp9hskjhf',
'test' => [
0 => '/tmp/php/asifu2gp3',
1 => '',
],
],
'error' => [
'other' => '0',
'test' => [
0 => '0',
1 => '4',
],
],
'size' => [
'other' => '421',
'test' => [
0 => '32',
1 => '0',
],
],
],
],
[
'file' => [
0 => new UploadedFile(
'/tmp/php/hp9hskjhf',
123,
UPLOAD_ERR_OK,
'MyFile.txt',
'text/plain'
),
1 => new UploadedFile(
'/tmp/php/php1h4j1o',
7349,
UPLOAD_ERR_OK,
'Image.png',
'image/png'
),
2 => new UploadedFile(
'/tmp/php/w0ensl4ar',
null,
UPLOAD_ERR_OK
),
],
'minimum_data' => [
0 => new UploadedFile(
'/tmp/php/hp9hskjhf',
0,
UPLOAD_ERR_OK
),
],
'nested' => [
'other' => new UploadedFile(
'/tmp/php/hp9hskjhf',
421,
UPLOAD_ERR_OK,
'Flag.txt',
'text/plain'
),
'test' => [
0 => new UploadedFile(
'/tmp/php/asifu2gp3',
32,
UPLOAD_ERR_OK,
'Stuff.txt',
'text/plain'
),
1 => new UploadedFile(
'',
0,
UPLOAD_ERR_NO_FILE,
'',
''
),
],
],
],
],
];
}
/**
* @dataProvider dataNormalizeFiles
*/
public function testNormalizeFiles($files, $expected): void
{
$result = ServerRequest::normalizeFiles($files);
self::assertEquals($expected, $result);
}
public function testNormalizeFilesRaisesException(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Invalid value in files specification');
ServerRequest::normalizeFiles(['test' => 'something']);
}
public function dataGetUriFromGlobals(): iterable
{
$server = [
'REQUEST_URI' => '/blog/article.php?id=10&user=foo',
'SERVER_PORT' => '443',
'SERVER_ADDR' => '217.112.82.20',
'SERVER_NAME' => 'www.example.org',
'SERVER_PROTOCOL' => 'HTTP/1.1',
'REQUEST_METHOD' => 'POST',
'QUERY_STRING' => 'id=10&user=foo',
'DOCUMENT_ROOT' => '/path/to/your/server/root/',
'HTTP_HOST' => 'www.example.org',
'HTTPS' => 'on',
'REMOTE_ADDR' => '193.60.168.69',
'REMOTE_PORT' => '5390',
'SCRIPT_NAME' => '/blog/article.php',
'SCRIPT_FILENAME' => '/path/to/your/server/root/blog/article.php',
'PHP_SELF' => '/blog/article.php',
];
return [
'HTTPS request' => [
'https://www.example.org/blog/article.php?id=10&user=foo',
$server,
],
'HTTPS request with different on value' => [
'https://www.example.org/blog/article.php?id=10&user=foo',
array_merge($server, ['HTTPS' => '1']),
],
'HTTP request' => [
'http://www.example.org/blog/article.php?id=10&user=foo',
array_merge($server, ['HTTPS' => 'off', 'SERVER_PORT' => '80']),
],
'HTTP_HOST missing -> fallback to SERVER_NAME' => [
'https://www.example.org/blog/article.php?id=10&user=foo',
array_merge($server, ['HTTP_HOST' => null]),
],
'HTTP_HOST and SERVER_NAME missing -> fallback to SERVER_ADDR' => [
'https://217.112.82.20/blog/article.php?id=10&user=foo',
array_merge($server, ['HTTP_HOST' => null, 'SERVER_NAME' => null]),
],
'Query string with ?' => [
'https://www.example.org/path?continue=https://example.com/path?param=1',
array_merge($server, ['REQUEST_URI' => '/path?continue=https://example.com/path?param=1', 'QUERY_STRING' => '']),
],
'No query String' => [
'https://www.example.org/blog/article.php',
array_merge($server, ['REQUEST_URI' => '/blog/article.php', 'QUERY_STRING' => '']),
],
'Host header with port' => [
'https://www.example.org:8324/blog/article.php?id=10&user=foo',
array_merge($server, ['HTTP_HOST' => 'www.example.org:8324']),
],
'IPv6 local loopback address' => [
'https://[::1]:8000/blog/article.php?id=10&user=foo',
array_merge($server, ['HTTP_HOST' => '[::1]:8000']),
],
'Invalid host' => [
'https://localhost/blog/article.php?id=10&user=foo',
array_merge($server, ['HTTP_HOST' => 'a:b']),
],
'Different port with SERVER_PORT' => [
'https://www.example.org:8324/blog/article.php?id=10&user=foo',
array_merge($server, ['SERVER_PORT' => '8324']),
],
'REQUEST_URI missing query string' => [
'https://www.example.org/blog/article.php?id=10&user=foo',
array_merge($server, ['REQUEST_URI' => '/blog/article.php']),
],
'Empty server variable' => [
'http://localhost',
[],
],
];
}
/**
* @dataProvider dataGetUriFromGlobals
*/
public function testGetUriFromGlobals($expected, $serverParams): void
{
$_SERVER = $serverParams;
self::assertEquals(new Uri($expected), ServerRequest::getUriFromGlobals());
}
public function testFromGlobals(): void
{
$_SERVER = [
'REQUEST_URI' => '/blog/article.php?id=10&user=foo',
'SERVER_PORT' => '443',
'SERVER_ADDR' => '217.112.82.20',
'SERVER_NAME' => 'www.example.org',
'SERVER_PROTOCOL' => 'HTTP/1.1',
'REQUEST_METHOD' => 'POST',
'QUERY_STRING' => 'id=10&user=foo',
'DOCUMENT_ROOT' => '/path/to/your/server/root/',
'CONTENT_TYPE' => 'text/plain',
'HTTP_HOST' => 'www.example.org',
'HTTP_ACCEPT' => 'text/html',
'HTTP_REFERRER' => 'https://example.com',
'HTTP_USER_AGENT' => 'My User Agent',
'HTTPS' => 'on',
'REMOTE_ADDR' => '193.60.168.69',
'REMOTE_PORT' => '5390',
'SCRIPT_NAME' => '/blog/article.php',
'SCRIPT_FILENAME' => '/path/to/your/server/root/blog/article.php',
'PHP_SELF' => '/blog/article.php',
];
$_COOKIE = [
'logged-in' => 'yes!',
];
$_POST = [
'name' => 'Pesho',
'email' => 'pesho@example.com',
];
$_GET = [
'id' => 10,
'user' => 'foo',
];
$_FILES = [
'file' => [
'name' => 'MyFile.txt',
'type' => 'text/plain',
'tmp_name' => '/tmp/php/php1h4j1o',
'error' => UPLOAD_ERR_OK,
'size' => 123,
],
];
$server = ServerRequest::fromGlobals();
self::assertSame('POST', $server->getMethod());
self::assertEquals([
'Host' => ['www.example.org'],
'Content-Type' => ['text/plain'],
'Accept' => ['text/html'],
'Referrer' => ['https://example.com'],
'User-Agent' => ['My User Agent'],
], $server->getHeaders());
self::assertSame('', (string) $server->getBody());
self::assertSame('1.1', $server->getProtocolVersion());
self::assertSame($_COOKIE, $server->getCookieParams());
self::assertSame($_POST, $server->getParsedBody());
self::assertSame($_GET, $server->getQueryParams());
self::assertEquals(
new Uri('https://www.example.org/blog/article.php?id=10&user=foo'),
$server->getUri()
);
$expectedFiles = [
'file' => new UploadedFile(
'/tmp/php/php1h4j1o',
123,
UPLOAD_ERR_OK,
'MyFile.txt',
'text/plain'
),
];
self::assertEquals($expectedFiles, $server->getUploadedFiles());
}
public function testUploadedFiles(): void
{
$request1 = new ServerRequest('GET', '/');
$files = [
'file' => new UploadedFile('test', 123, UPLOAD_ERR_OK),
];
$request2 = $request1->withUploadedFiles($files);
self::assertNotSame($request2, $request1);
self::assertSame([], $request1->getUploadedFiles());
self::assertSame($files, $request2->getUploadedFiles());
}
public function testServerParams(): void
{
$params = ['name' => 'value'];
$request = new ServerRequest('GET', '/', [], null, '1.1', $params);
self::assertSame($params, $request->getServerParams());
}
public function testCookieParams(): void
{
$request1 = new ServerRequest('GET', '/');
$params = ['name' => 'value'];
$request2 = $request1->withCookieParams($params);
self::assertNotSame($request2, $request1);
self::assertEmpty($request1->getCookieParams());
self::assertSame($params, $request2->getCookieParams());
}
public function testQueryParams(): void
{
$request1 = new ServerRequest('GET', '/');
$params = ['name' => 'value'];
$request2 = $request1->withQueryParams($params);
self::assertNotSame($request2, $request1);
self::assertEmpty($request1->getQueryParams());
self::assertSame($params, $request2->getQueryParams());
}
public function testParsedBody(): void
{
$request1 = new ServerRequest('GET', '/');
$params = ['name' => 'value'];
$request2 = $request1->withParsedBody($params);
self::assertNotSame($request2, $request1);
self::assertEmpty($request1->getParsedBody());
self::assertSame($params, $request2->getParsedBody());
}
public function testAttributes(): void
{
$request1 = new ServerRequest('GET', '/');
$request2 = $request1->withAttribute('name', 'value');
$request3 = $request2->withAttribute('other', 'otherValue');
$request4 = $request3->withoutAttribute('other');
$request5 = $request3->withoutAttribute('unknown');
self::assertNotSame($request2, $request1);
self::assertNotSame($request3, $request2);
self::assertNotSame($request4, $request3);
self::assertSame($request5, $request3);
self::assertSame([], $request1->getAttributes());
self::assertNull($request1->getAttribute('name'));
self::assertSame(
'something',
$request1->getAttribute('name', 'something'),
'Should return the default value'
);
self::assertSame('value', $request2->getAttribute('name'));
self::assertSame(['name' => 'value'], $request2->getAttributes());
self::assertSame(['name' => 'value', 'other' => 'otherValue'], $request3->getAttributes());
self::assertSame(['name' => 'value'], $request4->getAttributes());
}
public function testNullAttribute(): void
{
$request = (new ServerRequest('GET', '/'))->withAttribute('name', null);
self::assertSame(['name' => null], $request->getAttributes());
self::assertNull($request->getAttribute('name', 'different-default'));
$requestWithoutAttribute = $request->withoutAttribute('name');
self::assertSame([], $requestWithoutAttribute->getAttributes());
self::assertSame('different-default', $requestWithoutAttribute->getAttribute('name', 'different-default'));
}
}

148
vendor/guzzlehttp/psr7/tests/StreamDecoratorTraitTest.php

@ -1,148 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\StreamDecoratorTrait;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\StreamInterface;
class Str implements StreamInterface
{
use StreamDecoratorTrait;
/** @var StreamInterface */
private $stream;
}
/**
* @covers \GuzzleHttp\Psr7\StreamDecoratorTrait
*/
class StreamDecoratorTraitTest extends TestCase
{
/** @var StreamInterface */
private $a;
/** @var StreamInterface */
private $b;
/** @var resource */
private $c;
protected function setUp(): void
{
$this->c = fopen('php://temp', 'r+');
fwrite($this->c, 'foo');
fseek($this->c, 0);
$this->a = Psr7\Utils::streamFor($this->c);
$this->b = new Str($this->a);
}
/**
* @requires PHP < 7.4
*/
public function testCatchesExceptionsWhenCastingToString(): void
{
$s = $this->createMock(Str::class);
$s->expects(self::once())
->method('read')
->willThrowException(new \RuntimeException('foo'));
$msg = '';
set_error_handler(function (int $errNo, string $str) use (&$msg): void {
$msg = $str;
});
echo new Str($s);
restore_error_handler();
self::assertStringContainsString('foo', $msg);
}
public function testToString(): void
{
self::assertSame('foo', (string) $this->b);
}
public function testHasSize(): void
{
self::assertSame(3, $this->b->getSize());
}
public function testReads(): void
{
self::assertSame('foo', $this->b->read(10));
}
public function testCheckMethods(): void
{
self::assertSame($this->a->isReadable(), $this->b->isReadable());
self::assertSame($this->a->isWritable(), $this->b->isWritable());
self::assertSame($this->a->isSeekable(), $this->b->isSeekable());
}
public function testSeeksAndTells(): void
{
$this->b->seek(1);
self::assertSame(1, $this->a->tell());
self::assertSame(1, $this->b->tell());
$this->b->seek(0);
self::assertSame(0, $this->a->tell());
self::assertSame(0, $this->b->tell());
$this->b->seek(0, SEEK_END);
self::assertSame(3, $this->a->tell());
self::assertSame(3, $this->b->tell());
}
public function testGetsContents(): void
{
self::assertSame('foo', $this->b->getContents());
self::assertSame('', $this->b->getContents());
$this->b->seek(1);
self::assertSame('oo', $this->b->getContents());
}
public function testCloses(): void
{
$this->b->close();
self::assertFalse(is_resource($this->c));
}
public function testDetaches(): void
{
$this->b->detach();
self::assertFalse($this->b->isReadable());
}
public function testWrapsMetadata(): void
{
self::assertSame($this->b->getMetadata(), $this->a->getMetadata());
self::assertSame($this->b->getMetadata('uri'), $this->a->getMetadata('uri'));
}
public function testWrapsWrites(): void
{
$this->b->seek(0, SEEK_END);
$this->b->write('foo');
self::assertSame('foofoo', (string) $this->a);
}
public function testThrowsWithInvalidGetter(): void
{
$this->expectException(\UnexpectedValueException::class);
$this->b->foo;
}
public function testThrowsWhenGetterNotImplemented(): void
{
$this->expectException(\BadMethodCallException::class);
$s = new BadStream();
$s->stream;
}
}
class BadStream
{
use StreamDecoratorTrait;
public function __construct()
{
}
}

447
vendor/guzzlehttp/psr7/tests/StreamTest.php

@ -1,447 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7\FnStream;
use GuzzleHttp\Psr7\Stream;
use GuzzleHttp\Psr7\StreamWrapper;
use PHPUnit\Framework\TestCase;
/**
* @covers \GuzzleHttp\Psr7\Stream
*/
class StreamTest extends TestCase
{
public static $isFReadError = false;
public function testConstructorThrowsExceptionOnInvalidArgument(): void
{
$this->expectException(\InvalidArgumentException::class);
new Stream(true);
}
public function testConstructorInitializesProperties(): void
{
$handle = fopen('php://temp', 'r+');
fwrite($handle, 'data');
$stream = new Stream($handle);
self::assertTrue($stream->isReadable());
self::assertTrue($stream->isWritable());
self::assertTrue($stream->isSeekable());
self::assertSame('php://temp', $stream->getMetadata('uri'));
self::assertIsArray($stream->getMetadata());
self::assertSame(4, $stream->getSize());
self::assertFalse($stream->eof());
$stream->close();
}
public function testConstructorInitializesPropertiesWithRbPlus(): void
{
$handle = fopen('php://temp', 'rb+');
fwrite($handle, 'data');
$stream = new Stream($handle);
self::assertTrue($stream->isReadable());
self::assertTrue($stream->isWritable());
self::assertTrue($stream->isSeekable());
self::assertSame('php://temp', $stream->getMetadata('uri'));
self::assertIsArray($stream->getMetadata());
self::assertSame(4, $stream->getSize());
self::assertFalse($stream->eof());
$stream->close();
}
public function testStreamClosesHandleOnDestruct(): void
{
$handle = fopen('php://temp', 'r');
$stream = new Stream($handle);
unset($stream);
self::assertFalse(is_resource($handle));
}
public function testConvertsToString(): void
{
$handle = fopen('php://temp', 'w+');
fwrite($handle, 'data');
$stream = new Stream($handle);
self::assertSame('data', (string) $stream);
self::assertSame('data', (string) $stream);
$stream->close();
}
public function testConvertsToStringNonSeekableStream(): void
{
$handle = popen('echo foo', 'r');
$stream = new Stream($handle);
self::assertFalse($stream->isSeekable());
self::assertSame('foo', trim((string) $stream));
}
public function testConvertsToStringNonSeekablePartiallyReadStream(): void
{
$handle = popen('echo bar', 'r');
$stream = new Stream($handle);
$firstLetter = $stream->read(1);
self::assertFalse($stream->isSeekable());
self::assertSame('b', $firstLetter);
self::assertSame('ar', trim((string) $stream));
}
public function testGetsContents(): void
{
$handle = fopen('php://temp', 'w+');
fwrite($handle, 'data');
$stream = new Stream($handle);
self::assertSame('', $stream->getContents());
$stream->seek(0);
self::assertSame('data', $stream->getContents());
self::assertSame('', $stream->getContents());
$stream->close();
}
public function testChecksEof(): void
{
$handle = fopen('php://temp', 'w+');
fwrite($handle, 'data');
$stream = new Stream($handle);
self::assertSame(4, $stream->tell(), 'Stream cursor already at the end');
self::assertFalse($stream->eof(), 'Stream still not eof');
self::assertSame('', $stream->read(1), 'Need to read one more byte to reach eof');
self::assertTrue($stream->eof());
$stream->close();
}
public function testGetSize(): void
{
$size = filesize(__FILE__);
$handle = fopen(__FILE__, 'r');
$stream = new Stream($handle);
self::assertSame($size, $stream->getSize());
// Load from cache
self::assertSame($size, $stream->getSize());
$stream->close();
}
public function testEnsuresSizeIsConsistent(): void
{
$h = fopen('php://temp', 'w+');
self::assertSame(3, fwrite($h, 'foo'));
$stream = new Stream($h);
self::assertSame(3, $stream->getSize());
self::assertSame(4, $stream->write('test'));
self::assertSame(7, $stream->getSize());
self::assertSame(7, $stream->getSize());
$stream->close();
}
public function testProvidesStreamPosition(): void
{
$handle = fopen('php://temp', 'w+');
$stream = new Stream($handle);
self::assertSame(0, $stream->tell());
$stream->write('foo');
self::assertSame(3, $stream->tell());
$stream->seek(1);
self::assertSame(1, $stream->tell());
self::assertSame(ftell($handle), $stream->tell());
$stream->close();
}
public function testDetachStreamAndClearProperties(): void
{
$handle = fopen('php://temp', 'r');
$stream = new Stream($handle);
self::assertSame($handle, $stream->detach());
self::assertIsResource($handle, 'Stream is not closed');
self::assertNull($stream->detach());
$this->assertStreamStateAfterClosedOrDetached($stream);
$stream->close();
}
public function testCloseResourceAndClearProperties(): void
{
$handle = fopen('php://temp', 'r');
$stream = new Stream($handle);
$stream->close();
self::assertFalse(is_resource($handle));
$this->assertStreamStateAfterClosedOrDetached($stream);
}
private function assertStreamStateAfterClosedOrDetached(Stream $stream): void
{
self::assertFalse($stream->isReadable());
self::assertFalse($stream->isWritable());
self::assertFalse($stream->isSeekable());
self::assertNull($stream->getSize());
self::assertSame([], $stream->getMetadata());
self::assertNull($stream->getMetadata('foo'));
$throws = function (callable $fn): void {
try {
$fn();
} catch (\Exception $e) {
$this->assertStringContainsString('Stream is detached', $e->getMessage());
return;
}
$this->fail('Exception should be thrown after the stream is detached.');
};
$throws(function () use ($stream): void {
$stream->read(10);
});
$throws(function () use ($stream): void {
$stream->write('bar');
});
$throws(function () use ($stream): void {
$stream->seek(10);
});
$throws(function () use ($stream): void {
$stream->tell();
});
$throws(function () use ($stream): void {
$stream->eof();
});
$throws(function () use ($stream): void {
$stream->getContents();
});
if (\PHP_VERSION_ID >= 70400) {
$throws(function () use ($stream): void {
(string) $stream;
});
} else {
$errors = [];
set_error_handler(function (int $errorNumber, string $errorMessage) use (&$errors): void {
$errors[] = ['message' => $errorMessage, 'number' => $errorNumber];
});
self::assertSame('', (string) $stream);
restore_error_handler();
self::assertCount(1, $errors);
self::assertStringStartsWith('GuzzleHttp\Psr7\Stream::__toString exception', $errors[0]['message']);
self::assertSame(E_USER_ERROR, $errors[0]['number']);
}
}
public function testStreamReadingWithZeroLength(): void
{
$r = fopen('php://temp', 'r');
$stream = new Stream($r);
self::assertSame('', $stream->read(0));
$stream->close();
}
public function testStreamReadingWithNegativeLength(): void
{
$r = fopen('php://temp', 'r');
$stream = new Stream($r);
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('Length parameter cannot be negative');
try {
$stream->read(-1);
} catch (\Exception $e) {
$stream->close();
throw $e;
}
$stream->close();
}
public function testStreamReadingFreadFalse(): void
{
self::$isFReadError = true;
$r = fopen('php://temp', 'r');
$stream = new Stream($r);
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('Unable to read from stream');
try {
$stream->read(1);
} catch (\Exception $e) {
self::$isFReadError = false;
$stream->close();
throw $e;
}
self::$isFReadError = false;
$stream->close();
}
public function testStreamReadingFreadException(): void
{
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('Unable to read from stream');
$r = StreamWrapper::getResource(new FnStream([
'read' => function ($len): string {
throw new \ErrorException('Some error');
},
'isReadable' => function (): bool {
return true;
},
'isWritable' => function (): bool {
return false;
},
'eof' => function (): bool {
return false;
},
]));
$stream = new Stream($r);
$stream->read(1);
}
/**
* @requires extension zlib
*
* @dataProvider gzipModeProvider
*/
public function testGzipStreamModes(string $mode, bool $readable, bool $writable): void
{
$r = gzopen('php://temp', $mode);
$stream = new Stream($r);
self::assertSame($readable, $stream->isReadable());
self::assertSame($writable, $stream->isWritable());
$stream->close();
}
public function gzipModeProvider(): iterable
{
return [
['mode' => 'rb9', 'readable' => true, 'writable' => false],
['mode' => 'wb2', 'readable' => false, 'writable' => true],
];
}
/**
* @dataProvider readableModeProvider
*/
public function testReadableStream(string $mode): void
{
$r = fopen('php://temp', $mode);
$stream = new Stream($r);
self::assertTrue($stream->isReadable());
$stream->close();
}
public function readableModeProvider(): iterable
{
return [
['r'],
['w+'],
['r+'],
['x+'],
['c+'],
['rb'],
['w+b'],
['r+b'],
['x+b'],
['c+b'],
['rt'],
['w+t'],
['r+t'],
['x+t'],
['c+t'],
['a+'],
['rb+'],
];
}
public function testWriteOnlyStreamIsNotReadable(): void
{
$r = fopen('php://output', 'w');
$stream = new Stream($r);
self::assertFalse($stream->isReadable());
$stream->close();
}
/**
* @dataProvider writableModeProvider
*/
public function testWritableStream(string $mode): void
{
$r = fopen('php://temp', $mode);
$stream = new Stream($r);
self::assertTrue($stream->isWritable());
$stream->close();
}
public function writableModeProvider(): iterable
{
return [
['w'],
['w+'],
['rw'],
['r+'],
['x+'],
['c+'],
['wb'],
['w+b'],
['r+b'],
['rb+'],
['x+b'],
['c+b'],
['w+t'],
['r+t'],
['x+t'],
['c+t'],
['a'],
['a+'],
];
}
public function testReadOnlyStreamIsNotWritable(): void
{
$r = fopen('php://input', 'r');
$stream = new Stream($r);
self::assertFalse($stream->isWritable());
$stream->close();
}
public function testCannotReadUnreadableStream(): void
{
$r = fopen(tempnam(sys_get_temp_dir(), 'guzzle-psr7-'), 'w');
$stream = new Stream($r);
$stream->write('Hello world!!');
$stream->seek(0);
$this->expectException(\RuntimeException::class);
try {
$stream->getContents();
} finally {
$stream->close();
}
}
}
namespace GuzzleHttp\Psr7;
use GuzzleHttp\Tests\Psr7\StreamTest;
function fread($handle, $length)
{
return StreamTest::$isFReadError ? false : \fread($handle, $length);
}

202
vendor/guzzlehttp/psr7/tests/StreamWrapperTest.php

@ -1,202 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\StreamWrapper;
use GuzzleHttp\Psr7\Utils;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\StreamInterface;
/**
* @covers \GuzzleHttp\Psr7\StreamWrapper
*/
class StreamWrapperTest extends TestCase
{
public function testResource(): void
{
$stream = Utils::streamFor('foo');
$handle = StreamWrapper::getResource($stream);
self::assertSame('foo', fread($handle, 3));
self::assertSame(3, ftell($handle));
self::assertSame(3, fwrite($handle, 'bar'));
self::assertSame(0, fseek($handle, 0));
self::assertSame('foobar', fread($handle, 6));
self::assertSame('', fread($handle, 1));
self::assertTrue(feof($handle));
$stBlksize = defined('PHP_WINDOWS_VERSION_BUILD') ? -1 : 0;
self::assertEquals([
'dev' => 0,
'ino' => 0,
'mode' => 33206,
'nlink' => 0,
'uid' => 0,
'gid' => 0,
'rdev' => 0,
'size' => 6,
'atime' => 0,
'mtime' => 0,
'ctime' => 0,
'blksize' => $stBlksize,
'blocks' => $stBlksize,
0 => 0,
1 => 0,
2 => 33206,
3 => 0,
4 => 0,
5 => 0,
6 => 0,
7 => 6,
8 => 0,
9 => 0,
10 => 0,
11 => $stBlksize,
12 => $stBlksize,
], fstat($handle));
self::assertTrue(fclose($handle));
self::assertSame('foobar', (string) $stream);
}
public function testStreamContext(): void
{
$stream = Utils::streamFor('foo');
self::assertSame('foo', file_get_contents('guzzle://stream', false, StreamWrapper::createStreamContext($stream)));
}
public function testStreamCast(): void
{
$streams = [
StreamWrapper::getResource(Utils::streamFor('foo')),
StreamWrapper::getResource(Utils::streamFor('bar')),
];
$write = null;
$except = null;
self::assertIsInt(stream_select($streams, $write, $except, 0));
}
public function testValidatesStream(): void
{
$stream = $this->createMock(StreamInterface::class);
$stream->expects(self::once())
->method('isReadable')
->willReturn(false);
$stream->expects(self::once())
->method('isWritable')
->willReturn(false);
$this->expectException(\InvalidArgumentException::class);
StreamWrapper::getResource($stream);
}
public function testReturnsFalseWhenStreamDoesNotExist(): void
{
$this->expectWarning();
fopen('guzzle://foo', 'r');
}
public function testCanOpenReadonlyStream(): void
{
$stream = $this->createMock(StreamInterface::class);
$stream->expects(self::once())
->method('isReadable')
->willReturn(false);
$stream->expects(self::once())
->method('isWritable')
->willReturn(true);
$r = StreamWrapper::getResource($stream);
self::assertIsResource($r);
fclose($r);
}
public function testUrlStat(): void
{
StreamWrapper::register();
$stBlksize = defined('PHP_WINDOWS_VERSION_BUILD') ? -1 : 0;
self::assertEquals(
[
'dev' => 0,
'ino' => 0,
'mode' => 0,
'nlink' => 0,
'uid' => 0,
'gid' => 0,
'rdev' => 0,
'size' => 0,
'atime' => 0,
'mtime' => 0,
'ctime' => 0,
'blksize' => $stBlksize,
'blocks' => $stBlksize,
0 => 0,
1 => 0,
2 => 0,
3 => 0,
4 => 0,
5 => 0,
6 => 0,
7 => 0,
8 => 0,
9 => 0,
10 => 0,
11 => $stBlksize,
12 => $stBlksize,
],
stat('guzzle://stream')
);
}
/**
* @requires extension xmlreader
*/
public function testXmlReaderWithStream(): void
{
$stream = Utils::streamFor('<?xml version="1.0" encoding="utf-8"?><foo />');
StreamWrapper::register();
libxml_set_streams_context(StreamWrapper::createStreamContext($stream));
$reader = new \XMLReader();
self::assertTrue($reader->open('guzzle://stream'));
self::assertTrue($reader->read());
self::assertSame('foo', $reader->name);
}
/**
* @requires extension xmlreader
*/
public function testXmlWriterWithStream(): void
{
$stream = Utils::streamFor(fopen('php://memory', 'wb'));
StreamWrapper::register();
libxml_set_streams_context(StreamWrapper::createStreamContext($stream));
$writer = new \XMLWriter();
self::assertTrue($writer->openURI('guzzle://stream'));
self::assertTrue($writer->startDocument());
self::assertTrue($writer->writeElement('foo'));
self::assertTrue($writer->endDocument());
$stream->rewind();
self::assertXmlStringEqualsXmlString('<?xml version="1.0"?><foo />', (string) $stream);
}
public function testWrappedNullSizedStreamStaysNullSized(): void
{
$nullSizedStream = new Psr7\PumpStream(function () { return ''; });
$this->assertNull($nullSizedStream->getSize());
$resource = StreamWrapper::getResource($nullSizedStream);
$stream = Utils::streamFor($resource);
$this->assertNull($stream->getSize());
}
}

210
vendor/guzzlehttp/psr7/tests/UploadedFileTest.php

@ -1,210 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7\Stream;
use GuzzleHttp\Psr7\UploadedFile;
use PHPUnit\Framework\TestCase;
use ReflectionProperty;
/**
* @covers \GuzzleHttp\Psr7\UploadedFile
*/
class UploadedFileTest extends TestCase
{
private $cleanup;
protected function setUp(): void
{
$this->cleanup = [];
}
protected function tearDown(): void
{
foreach ($this->cleanup as $file) {
if (is_scalar($file) && file_exists($file)) {
unlink($file);
}
}
}
public function invalidStreams()
{
return [
'null' => [null],
'true' => [true],
'false' => [false],
'int' => [1],
'float' => [1.1],
'array' => [['filename']],
'object' => [(object) ['filename']],
];
}
/**
* @dataProvider invalidStreams
*/
public function testRaisesExceptionOnInvalidStreamOrFile($streamOrFile): void
{
$this->expectException(\InvalidArgumentException::class);
new UploadedFile($streamOrFile, 0, UPLOAD_ERR_OK);
}
public function testGetStreamReturnsOriginalStreamObject(): void
{
$stream = new Stream(fopen('php://temp', 'r'));
$upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
self::assertSame($stream, $upload->getStream());
}
public function testGetStreamReturnsWrappedPhpStream(): void
{
$stream = fopen('php://temp', 'wb+');
$upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
$uploadStream = $upload->getStream()->detach();
self::assertSame($stream, $uploadStream);
}
public function testGetStreamReturnsStreamForFile(): void
{
$this->cleanup[] = $stream = tempnam(sys_get_temp_dir(), 'stream_file');
$upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
$uploadStream = $upload->getStream();
$r = new ReflectionProperty($uploadStream, 'filename');
$r->setAccessible(true);
self::assertSame($stream, $r->getValue($uploadStream));
}
public function testSuccessful(): void
{
$stream = \GuzzleHttp\Psr7\Utils::streamFor('Foo bar!');
$upload = new UploadedFile($stream, $stream->getSize(), UPLOAD_ERR_OK, 'filename.txt', 'text/plain');
self::assertSame($stream->getSize(), $upload->getSize());
self::assertSame('filename.txt', $upload->getClientFilename());
self::assertSame('text/plain', $upload->getClientMediaType());
$this->cleanup[] = $to = tempnam(sys_get_temp_dir(), 'successful');
$upload->moveTo($to);
self::assertFileExists($to);
self::assertSame($stream->__toString(), file_get_contents($to));
}
public function invalidMovePaths(): iterable
{
return [
'null' => [null],
'true' => [true],
'false' => [false],
'int' => [1],
'float' => [1.1],
'empty' => [''],
'array' => [['filename']],
'object' => [(object) ['filename']],
];
}
/**
* @dataProvider invalidMovePaths
*/
public function testMoveRaisesExceptionForInvalidPath($path): void
{
$stream = \GuzzleHttp\Psr7\Utils::streamFor('Foo bar!');
$upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('path');
$upload->moveTo($path);
}
public function testMoveCannotBeCalledMoreThanOnce(): void
{
$stream = \GuzzleHttp\Psr7\Utils::streamFor('Foo bar!');
$upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
$this->cleanup[] = $to = tempnam(sys_get_temp_dir(), 'diac');
$upload->moveTo($to);
self::assertFileExists($to);
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('moved');
$upload->moveTo($to);
}
public function testCannotRetrieveStreamAfterMove(): void
{
$stream = \GuzzleHttp\Psr7\Utils::streamFor('Foo bar!');
$upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
$this->cleanup[] = $to = tempnam(sys_get_temp_dir(), 'diac');
$upload->moveTo($to);
self::assertFileExists($to);
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('moved');
$upload->getStream();
}
public function nonOkErrorStatus(): iterable
{
return [
'UPLOAD_ERR_INI_SIZE' => [UPLOAD_ERR_INI_SIZE],
'UPLOAD_ERR_FORM_SIZE' => [UPLOAD_ERR_FORM_SIZE],
'UPLOAD_ERR_PARTIAL' => [UPLOAD_ERR_PARTIAL],
'UPLOAD_ERR_NO_FILE' => [UPLOAD_ERR_NO_FILE],
'UPLOAD_ERR_NO_TMP_DIR' => [UPLOAD_ERR_NO_TMP_DIR],
'UPLOAD_ERR_CANT_WRITE' => [UPLOAD_ERR_CANT_WRITE],
'UPLOAD_ERR_EXTENSION' => [UPLOAD_ERR_EXTENSION],
];
}
/**
* @dataProvider nonOkErrorStatus
*/
public function testConstructorDoesNotRaiseExceptionForInvalidStreamWhenErrorStatusPresent($status): void
{
$uploadedFile = new UploadedFile('not ok', 0, $status);
self::assertSame($status, $uploadedFile->getError());
}
/**
* @dataProvider nonOkErrorStatus
*/
public function testMoveToRaisesExceptionWhenErrorStatusPresent($status): void
{
$uploadedFile = new UploadedFile('not ok', 0, $status);
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('upload error');
$uploadedFile->moveTo(__DIR__.'/'.bin2hex(random_bytes(20)));
}
/**
* @dataProvider nonOkErrorStatus
*/
public function testGetStreamRaisesExceptionWhenErrorStatusPresent($status): void
{
$uploadedFile = new UploadedFile('not ok', 0, $status);
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('upload error');
$uploadedFile->getStream();
}
public function testMoveToCreatesStreamIfOnlyAFilenameWasProvided(): void
{
$this->cleanup[] = $from = tempnam(sys_get_temp_dir(), 'copy_from');
$this->cleanup[] = $to = tempnam(sys_get_temp_dir(), 'copy_to');
copy(__FILE__, $from);
$uploadedFile = new UploadedFile($from, 100, UPLOAD_ERR_OK, basename($from), 'text/plain');
$uploadedFile->moveTo($to);
self::assertFileEquals(__FILE__, $to);
}
}

45
vendor/guzzlehttp/psr7/tests/UriComparatorTest.php

@ -1,45 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7\Uri;
use GuzzleHttp\Psr7\UriComparator;
use PHPUnit\Framework\TestCase;
/**
* @covers \GuzzleHttp\Psr7\UriComparator
*/
class UriComparatorTest extends TestCase
{
/**
* @dataProvider getCrossOriginExamples
*/
public function testIsCrossOrigin(string $original, string $modified, bool $expected): void
{
self::assertSame($expected, UriComparator::isCrossOrigin(new Uri($original), new Uri($modified)));
}
public function getCrossOriginExamples(): array
{
return [
['http://example.com/123', 'http://example.com/', false],
['http://example.com/123', 'http://example.com:80/', false],
['http://example.com:80/123', 'http://example.com/', false],
['http://example.com:80/123', 'http://example.com:80/', false],
['http://example.com/123', 'https://example.com/', true],
['http://example.com/123', 'http://www.example.com/', true],
['http://example.com/123', 'http://example.com:81/', true],
['http://example.com:80/123', 'http://example.com:81/', true],
['https://example.com/123', 'https://example.com/', false],
['https://example.com/123', 'https://example.com:443/', false],
['https://example.com:443/123', 'https://example.com/', false],
['https://example.com:443/123', 'https://example.com:443/', false],
['https://example.com/123', 'http://example.com/', true],
['https://example.com/123', 'https://www.example.com/', true],
['https://example.com/123', 'https://example.com:444/', true],
['https://example.com:443/123', 'https://example.com:444/', true],
];
}
}

180
vendor/guzzlehttp/psr7/tests/UriNormalizerTest.php

@ -1,180 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7\Uri;
use GuzzleHttp\Psr7\UriNormalizer;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\UriInterface;
/**
* @covers \GuzzleHttp\Psr7\UriNormalizer
*/
class UriNormalizerTest extends TestCase
{
public function testCapitalizePercentEncoding(): void
{
$actualEncoding = 'a%c2%7A%5eb%25%fa%fA%Fa';
$expectEncoding = 'a%C2%7A%5Eb%25%FA%FA%FA';
$uri = (new Uri())->withPath("/$actualEncoding")->withQuery($actualEncoding);
self::assertSame("/$actualEncoding?$actualEncoding", (string) $uri, 'Not normalized automatically beforehand');
$normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::CAPITALIZE_PERCENT_ENCODING);
self::assertInstanceOf(UriInterface::class, $normalizedUri);
self::assertSame("/$expectEncoding?$expectEncoding", (string) $normalizedUri);
}
/**
* @dataProvider getUnreservedCharacters
*/
public function testDecodeUnreservedCharacters(string $char): void
{
$percentEncoded = '%'.bin2hex($char);
// Add encoded reserved characters to test that those are not decoded and include the percent-encoded
// unreserved character both in lower and upper case to test the decoding is case-insensitive.
$encodedChars = $percentEncoded.'%2F%5B'.strtoupper($percentEncoded);
$uri = (new Uri())->withPath("/$encodedChars")->withQuery($encodedChars);
self::assertSame("/$encodedChars?$encodedChars", (string) $uri, 'Not normalized automatically beforehand');
$normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::DECODE_UNRESERVED_CHARACTERS);
self::assertInstanceOf(UriInterface::class, $normalizedUri);
self::assertSame("/$char%2F%5B$char?$char%2F%5B$char", (string) $normalizedUri);
}
public function getUnreservedCharacters(): iterable
{
$unreservedChars = array_merge(range('a', 'z'), range('A', 'Z'), range(0, 9), ['-', '.', '_', '~']);
return array_map(function ($char) {
return [(string) $char];
}, $unreservedChars);
}
/**
* @dataProvider getEmptyPathTestCases
*/
public function testConvertEmptyPath($uri, $expected): void
{
$normalizedUri = UriNormalizer::normalize(new Uri($uri), UriNormalizer::CONVERT_EMPTY_PATH);
self::assertInstanceOf(UriInterface::class, $normalizedUri);
self::assertSame($expected, (string) $normalizedUri);
}
public function getEmptyPathTestCases(): iterable
{
return [
['http://example.org', 'http://example.org/'],
['https://example.org', 'https://example.org/'],
['urn://example.org', 'urn://example.org'],
];
}
public function testRemoveDefaultHost(): void
{
$uri = new Uri('file://localhost/myfile');
$normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::REMOVE_DEFAULT_HOST);
self::assertInstanceOf(UriInterface::class, $normalizedUri);
self::assertSame('file:///myfile', (string) $normalizedUri);
}
public function testRemoveDefaultPort(): void
{
$uri = $this->createMock(UriInterface::class);
$uri->expects(self::any())->method('getScheme')->willReturn('http');
$uri->expects(self::any())->method('getPort')->willReturn(80);
$uri->expects(self::once())->method('withPort')->with(null)->willReturn(new Uri('http://example.org'));
$normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::REMOVE_DEFAULT_PORT);
self::assertInstanceOf(UriInterface::class, $normalizedUri);
self::assertNull($normalizedUri->getPort());
}
public function testRemoveDotSegments(): void
{
$uri = new Uri('http://example.org/../a/b/../c/./d.html');
$normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::REMOVE_DOT_SEGMENTS);
self::assertInstanceOf(UriInterface::class, $normalizedUri);
self::assertSame('http://example.org/a/c/d.html', (string) $normalizedUri);
}
public function testRemoveDotSegmentsOfAbsolutePathReference(): void
{
$uri = new Uri('/../a/b/../c/./d.html');
$normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::REMOVE_DOT_SEGMENTS);
self::assertInstanceOf(UriInterface::class, $normalizedUri);
self::assertSame('/a/c/d.html', (string) $normalizedUri);
}
public function testRemoveDotSegmentsOfRelativePathReference(): void
{
$uri = new Uri('../c/./d.html');
$normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::REMOVE_DOT_SEGMENTS);
self::assertInstanceOf(UriInterface::class, $normalizedUri);
self::assertSame('../c/./d.html', (string) $normalizedUri);
}
public function testRemoveDuplicateSlashes(): void
{
$uri = new Uri('http://example.org//foo///bar/bam.html');
$normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::REMOVE_DUPLICATE_SLASHES);
self::assertInstanceOf(UriInterface::class, $normalizedUri);
self::assertSame('http://example.org/foo/bar/bam.html', (string) $normalizedUri);
}
public function testSortQueryParameters(): void
{
$uri = new Uri('?lang=en&article=fred');
$normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::SORT_QUERY_PARAMETERS);
self::assertInstanceOf(UriInterface::class, $normalizedUri);
self::assertSame('?article=fred&lang=en', (string) $normalizedUri);
}
public function testSortQueryParametersWithSameKeys(): void
{
$uri = new Uri('?a=b&b=c&a=a&a&b=a&b=b&a=d&a=c');
$normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::SORT_QUERY_PARAMETERS);
self::assertInstanceOf(UriInterface::class, $normalizedUri);
self::assertSame('?a&a=a&a=b&a=c&a=d&b=a&b=b&b=c', (string) $normalizedUri);
}
/**
* @dataProvider getEquivalentTestCases
*/
public function testIsEquivalent(string $uri1, string $uri2, bool $expected): void
{
$equivalent = UriNormalizer::isEquivalent(new Uri($uri1), new Uri($uri2));
self::assertSame($expected, $equivalent);
}
public function getEquivalentTestCases(): iterable
{
return [
['http://example.org', 'http://example.org', true],
['hTTp://eXaMpLe.org', 'http://example.org', true],
['http://example.org/path?#', 'http://example.org/path', true],
['http://example.org:80', 'http://example.org/', true],
['http://example.org/../a/.././p%61th?%7a=%5e', 'http://example.org/path?z=%5E', true],
['https://example.org/', 'http://example.org/', false],
['https://example.org/', '//example.org/', false],
['//example.org/', '//example.org/', true],
['file:/myfile', 'file:///myfile', true],
['file:///myfile', 'file://localhost/myfile', true],
];
}
}

210
vendor/guzzlehttp/psr7/tests/UriResolverTest.php

@ -1,210 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7\Uri;
use GuzzleHttp\Psr7\UriResolver;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\UriInterface;
/**
* @covers \GuzzleHttp\Psr7\UriResolver
*/
class UriResolverTest extends TestCase
{
private const RFC3986_BASE = 'http://a/b/c/d;p?q';
/**
* @dataProvider getResolveTestCases
*/
public function testResolveUri(string $base, string $rel, string $expectedTarget): void
{
$baseUri = new Uri($base);
$targetUri = UriResolver::resolve($baseUri, new Uri($rel));
self::assertInstanceOf(UriInterface::class, $targetUri);
self::assertSame($expectedTarget, (string) $targetUri);
// This ensures there are no test cases that only work in the resolve() direction but not the
// opposite via relativize(). This can happen when both base and rel URI are relative-path
// references resulting in another relative-path URI.
self::assertSame($expectedTarget, (string) UriResolver::resolve($baseUri, $targetUri));
}
/**
* @dataProvider getResolveTestCases
*/
public function testRelativizeUri(string $base, string $expectedRelativeReference, string $target): void
{
$baseUri = new Uri($base);
$relativeUri = UriResolver::relativize($baseUri, new Uri($target));
self::assertInstanceOf(UriInterface::class, $relativeUri);
// There are test-cases with too many dot-segments and relative references that are equal like "." == "./".
// So apart from the same-as condition, this alternative success condition is necessary.
self::assertTrue(
$expectedRelativeReference === (string) $relativeUri
|| $target === (string) UriResolver::resolve($baseUri, $relativeUri),
sprintf(
'"%s" is not the correct relative reference as it does not resolve to the target URI from the base URI',
(string) $relativeUri
)
);
}
/**
* @dataProvider getRelativizeTestCases
*/
public function testRelativizeUriWithUniqueTests(string $base, string $target, string $expectedRelativeReference): void
{
$baseUri = new Uri($base);
$targetUri = new Uri($target);
$relativeUri = UriResolver::relativize($baseUri, $targetUri);
self::assertInstanceOf(UriInterface::class, $relativeUri);
self::assertSame($expectedRelativeReference, (string) $relativeUri);
self::assertSame((string) UriResolver::resolve($baseUri, $targetUri), (string) UriResolver::resolve($baseUri, $relativeUri));
}
public function getResolveTestCases(): iterable
{
return [
[self::RFC3986_BASE, 'g:h', 'g:h'],
[self::RFC3986_BASE, 'g', 'http://a/b/c/g'],
[self::RFC3986_BASE, './g', 'http://a/b/c/g'],
[self::RFC3986_BASE, 'g/', 'http://a/b/c/g/'],
[self::RFC3986_BASE, '/g', 'http://a/g'],
[self::RFC3986_BASE, '//g', 'http://g'],
[self::RFC3986_BASE, '?y', 'http://a/b/c/d;p?y'],
[self::RFC3986_BASE, 'g?y', 'http://a/b/c/g?y'],
[self::RFC3986_BASE, '#s', 'http://a/b/c/d;p?q#s'],
[self::RFC3986_BASE, 'g#s', 'http://a/b/c/g#s'],
[self::RFC3986_BASE, 'g?y#s', 'http://a/b/c/g?y#s'],
[self::RFC3986_BASE, ';x', 'http://a/b/c/;x'],
[self::RFC3986_BASE, 'g;x', 'http://a/b/c/g;x'],
[self::RFC3986_BASE, 'g;x?y#s', 'http://a/b/c/g;x?y#s'],
[self::RFC3986_BASE, '', self::RFC3986_BASE],
[self::RFC3986_BASE, '.', 'http://a/b/c/'],
[self::RFC3986_BASE, './', 'http://a/b/c/'],
[self::RFC3986_BASE, '..', 'http://a/b/'],
[self::RFC3986_BASE, '../', 'http://a/b/'],
[self::RFC3986_BASE, '../g', 'http://a/b/g'],
[self::RFC3986_BASE, '../..', 'http://a/'],
[self::RFC3986_BASE, '../../', 'http://a/'],
[self::RFC3986_BASE, '../../g', 'http://a/g'],
[self::RFC3986_BASE, '../../../g', 'http://a/g'],
[self::RFC3986_BASE, '../../../../g', 'http://a/g'],
[self::RFC3986_BASE, '/./g', 'http://a/g'],
[self::RFC3986_BASE, '/../g', 'http://a/g'],
[self::RFC3986_BASE, 'g.', 'http://a/b/c/g.'],
[self::RFC3986_BASE, '.g', 'http://a/b/c/.g'],
[self::RFC3986_BASE, 'g..', 'http://a/b/c/g..'],
[self::RFC3986_BASE, '..g', 'http://a/b/c/..g'],
[self::RFC3986_BASE, './../g', 'http://a/b/g'],
[self::RFC3986_BASE, 'foo////g', 'http://a/b/c/foo////g'],
[self::RFC3986_BASE, './g/.', 'http://a/b/c/g/'],
[self::RFC3986_BASE, 'g/./h', 'http://a/b/c/g/h'],
[self::RFC3986_BASE, 'g/../h', 'http://a/b/c/h'],
[self::RFC3986_BASE, 'g;x=1/./y', 'http://a/b/c/g;x=1/y'],
[self::RFC3986_BASE, 'g;x=1/../y', 'http://a/b/c/y'],
// dot-segments in the query or fragment
[self::RFC3986_BASE, 'g?y/./x', 'http://a/b/c/g?y/./x'],
[self::RFC3986_BASE, 'g?y/../x', 'http://a/b/c/g?y/../x'],
[self::RFC3986_BASE, 'g#s/./x', 'http://a/b/c/g#s/./x'],
[self::RFC3986_BASE, 'g#s/../x', 'http://a/b/c/g#s/../x'],
[self::RFC3986_BASE, 'g#s/../x', 'http://a/b/c/g#s/../x'],
[self::RFC3986_BASE, '?y#s', 'http://a/b/c/d;p?y#s'],
// base with fragment
['http://a/b/c?q#s', '?y', 'http://a/b/c?y'],
// base with user info
['http://u@a/b/c/d;p?q', '.', 'http://u@a/b/c/'],
['http://u:p@a/b/c/d;p?q', '.', 'http://u:p@a/b/c/'],
// path ending with slash or no slash at all
['http://a/b/c/d/', 'e', 'http://a/b/c/d/e'],
['urn:no-slash', 'e', 'urn:e'],
// path ending without slash and multi-segment relative part
['http://a/b/c', 'd/e', 'http://a/b/d/e'],
// falsey relative parts
[self::RFC3986_BASE, '//0', 'http://0'],
[self::RFC3986_BASE, '0', 'http://a/b/c/0'],
[self::RFC3986_BASE, '?0', 'http://a/b/c/d;p?0'],
[self::RFC3986_BASE, '#0', 'http://a/b/c/d;p?q#0'],
// absolute path base URI
['/a/b/', '', '/a/b/'],
['/a/b', '', '/a/b'],
['/', 'a', '/a'],
['/', 'a/b', '/a/b'],
['/a/b', 'g', '/a/g'],
['/a/b/c', './', '/a/b/'],
['/a/b/', '../', '/a/'],
['/a/b/c', '../', '/a/'],
['/a/b/', '../../x/y/z/', '/x/y/z/'],
['/a/b/c/d/e', '../../../c/d', '/a/c/d'],
['/a/b/c//', '../', '/a/b/c/'],
['/a/b/c/', './/', '/a/b/c//'],
['/a/b/c', '../../../../a', '/a'],
['/a/b/c', '../../../..', '/'],
// not actually a dot-segment
['/a/b/c', '..a/b..', '/a/b/..a/b..'],
// '' cannot be used as relative reference as it would inherit the base query component
['/a/b?q', 'b', '/a/b'],
['/a/b/?q', './', '/a/b/'],
// path with colon: "with:colon" would be the wrong relative reference
['/a/', './with:colon', '/a/with:colon'],
['/a/', 'b/with:colon', '/a/b/with:colon'],
['/a/', './:b/', '/a/:b/'],
// relative path references
['a', 'a/b', 'a/b'],
['', '', ''],
['', '..', ''],
['/', '..', '/'],
['urn:a/b', '..//a/b', 'urn:/a/b'],
// network path references
// empty base path and relative-path reference
['//example.com', 'a', '//example.com/a'],
// path starting with two slashes
['//example.com//two-slashes', './', '//example.com//'],
['//example.com', './/', '//example.com//'],
['//example.com/', './/', '//example.com//'],
// base URI has less components than relative URI
['/', '//a/b?q#h', '//a/b?q#h'],
['/', 'urn:/', 'urn:/'],
];
}
/**
* Some additional tests to getResolveTestCases() that only make sense for relativize.
*/
public function getRelativizeTestCases(): iterable
{
return [
// targets that are relative-path references are returned as-is
['a/b', 'b/c', 'b/c'],
['a/b/c', '../b/c', '../b/c'],
['a', '', ''],
['a', './', './'],
['a', 'a/..', 'a/..'],
['/a/b/?q', '?q#h', '?q#h'],
['/a/b/?q', '#h', '#h'],
['/a/b/?q', 'c#h', 'c#h'],
// If the base URI has a query but the target has none, we cannot return an empty path reference as it would
// inherit the base query component when resolving.
['/a/b/?q', '/a/b/#h', './#h'],
['/', '/#h', '#h'],
['/', '/', ''],
['http://a', 'http://a/', './'],
['urn:a/b?q', 'urn:x/y?q', '../x/y?q'],
['urn:', 'urn:/', './/'],
['urn:a/b?q', 'urn:', '../'],
// target URI has less components than base URI
['http://a/b/', '//a/b/c', 'c'],
['http://a/b/', '/b/c', 'c'],
['http://a/b/', '/x/y', '../x/y'],
['http://a/b/', '/', '../'],
// absolute target URI without authority but base URI has one
['urn://a/b/', 'urn:/b/', 'urn:/b/'],
];
}
}

722
vendor/guzzlehttp/psr7/tests/UriTest.php

@ -1,722 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7\Exception\MalformedUriException;
use GuzzleHttp\Psr7\Uri;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\UriInterface;
/**
* @covers \GuzzleHttp\Psr7\Uri
*/
class UriTest extends TestCase
{
public function testParsesProvidedUri(): void
{
$uri = new Uri('https://user:pass@example.com:8080/path/123?q=abc#test');
self::assertSame('https', $uri->getScheme());
self::assertSame('user:pass@example.com:8080', $uri->getAuthority());
self::assertSame('user:pass', $uri->getUserInfo());
self::assertSame('example.com', $uri->getHost());
self::assertSame(8080, $uri->getPort());
self::assertSame('/path/123', $uri->getPath());
self::assertSame('q=abc', $uri->getQuery());
self::assertSame('test', $uri->getFragment());
self::assertSame('https://user:pass@example.com:8080/path/123?q=abc#test', (string) $uri);
}
public function testCanTransformAndRetrievePartsIndividually(): void
{
$uri = (new Uri())
->withScheme('https')
->withUserInfo('user', 'pass')
->withHost('example.com')
->withPort(8080)
->withPath('/path/123')
->withQuery('q=abc')
->withFragment('test');
self::assertSame('https', $uri->getScheme());
self::assertSame('user:pass@example.com:8080', $uri->getAuthority());
self::assertSame('user:pass', $uri->getUserInfo());
self::assertSame('example.com', $uri->getHost());
self::assertSame(8080, $uri->getPort());
self::assertSame('/path/123', $uri->getPath());
self::assertSame('q=abc', $uri->getQuery());
self::assertSame('test', $uri->getFragment());
self::assertSame('https://user:pass@example.com:8080/path/123?q=abc#test', (string) $uri);
}
/**
* @dataProvider getValidUris
*/
public function testValidUrisStayValid(string $input): void
{
$uri = new Uri($input);
self::assertSame($input, (string) $uri);
}
/**
* @dataProvider getValidUris
*/
public function testFromParts(string $input): void
{
$uri = Uri::fromParts(parse_url($input));
self::assertSame($input, (string) $uri);
}
public function getValidUris(): iterable
{
return [
['urn:path-rootless'],
['urn:path:with:colon'],
['urn:/path-absolute'],
['urn:/'],
// only scheme with empty path
['urn:'],
// only path
['/'],
['relative/'],
['0'],
// same document reference
[''],
// network path without scheme
['//example.org'],
['//example.org/'],
['//example.org?q#h'],
// only query
['?q'],
['?q=abc&foo=bar'],
// only fragment
['#fragment'],
// dot segments are not removed automatically
['./foo/../bar'],
];
}
/**
* @dataProvider getInvalidUris
*/
public function testInvalidUrisThrowException(string $invalidUri): void
{
$this->expectException(MalformedUriException::class);
new Uri($invalidUri);
}
public function getInvalidUris(): iterable
{
return [
// parse_url() requires the host component which makes sense for http(s)
// but not when the scheme is not known or different. So '//' or '///' is
// currently invalid as well but should not according to RFC 3986.
['http://'],
['urn://host:with:colon'], // host cannot contain ":"
];
}
public function testPortMustBeValid(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Invalid port: 100000. Must be between 0 and 65535');
(new Uri())->withPort(100000);
}
public function testWithPortCannotBeNegative(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Invalid port: -1. Must be between 0 and 65535');
(new Uri())->withPort(-1);
}
public function testParseUriPortCannotBeNegative(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Unable to parse URI');
new Uri('//example.com:-1');
}
public function testSchemeMustHaveCorrectType(): void
{
$this->expectException(\InvalidArgumentException::class);
(new Uri())->withScheme([]);
}
public function testHostMustHaveCorrectType(): void
{
$this->expectException(\InvalidArgumentException::class);
(new Uri())->withHost([]);
}
public function testPathMustHaveCorrectType(): void
{
$this->expectException(\InvalidArgumentException::class);
(new Uri())->withPath([]);
}
public function testQueryMustHaveCorrectType(): void
{
$this->expectException(\InvalidArgumentException::class);
(new Uri())->withQuery([]);
}
public function testFragmentMustHaveCorrectType(): void
{
$this->expectException(\InvalidArgumentException::class);
(new Uri())->withFragment([]);
}
public function testCanParseFalseyUriParts(): void
{
$uri = new Uri('0://0:0@0/0?0#0');
self::assertSame('0', $uri->getScheme());
self::assertSame('0:0@0', $uri->getAuthority());
self::assertSame('0:0', $uri->getUserInfo());
self::assertSame('0', $uri->getHost());
self::assertSame('/0', $uri->getPath());
self::assertSame('0', $uri->getQuery());
self::assertSame('0', $uri->getFragment());
self::assertSame('0://0:0@0/0?0#0', (string) $uri);
}
public function testCanConstructFalseyUriParts(): void
{
$uri = (new Uri())
->withScheme('0')
->withUserInfo('0', '0')
->withHost('0')
->withPath('/0')
->withQuery('0')
->withFragment('0');
self::assertSame('0', $uri->getScheme());
self::assertSame('0:0@0', $uri->getAuthority());
self::assertSame('0:0', $uri->getUserInfo());
self::assertSame('0', $uri->getHost());
self::assertSame('/0', $uri->getPath());
self::assertSame('0', $uri->getQuery());
self::assertSame('0', $uri->getFragment());
self::assertSame('0://0:0@0/0?0#0', (string) $uri);
}
/**
* @dataProvider getPortTestCases
*/
public function testIsDefaultPort(string $scheme, ?int $port, bool $isDefaultPort): void
{
$uri = $this->createMock(UriInterface::class);
$uri->expects(self::any())->method('getScheme')->willReturn($scheme);
$uri->expects(self::any())->method('getPort')->willReturn($port);
self::assertSame($isDefaultPort, Uri::isDefaultPort($uri));
}
public function getPortTestCases(): iterable
{
return [
['http', null, true],
['http', 80, true],
['http', 8080, false],
['https', null, true],
['https', 443, true],
['https', 444, false],
['ftp', 21, true],
['gopher', 70, true],
['nntp', 119, true],
['news', 119, true],
['telnet', 23, true],
['tn3270', 23, true],
['imap', 143, true],
['pop', 110, true],
['ldap', 389, true],
];
}
public function testIsAbsolute(): void
{
self::assertTrue(Uri::isAbsolute(new Uri('http://example.org')));
self::assertFalse(Uri::isAbsolute(new Uri('//example.org')));
self::assertFalse(Uri::isAbsolute(new Uri('/abs-path')));
self::assertFalse(Uri::isAbsolute(new Uri('rel-path')));
}
public function testIsNetworkPathReference(): void
{
self::assertFalse(Uri::isNetworkPathReference(new Uri('http://example.org')));
self::assertTrue(Uri::isNetworkPathReference(new Uri('//example.org')));
self::assertFalse(Uri::isNetworkPathReference(new Uri('/abs-path')));
self::assertFalse(Uri::isNetworkPathReference(new Uri('rel-path')));
}
public function testIsAbsolutePathReference(): void
{
self::assertFalse(Uri::isAbsolutePathReference(new Uri('http://example.org')));
self::assertFalse(Uri::isAbsolutePathReference(new Uri('//example.org')));
self::assertTrue(Uri::isAbsolutePathReference(new Uri('/abs-path')));
self::assertTrue(Uri::isAbsolutePathReference(new Uri('/')));
self::assertFalse(Uri::isAbsolutePathReference(new Uri('rel-path')));
}
public function testIsRelativePathReference(): void
{
self::assertFalse(Uri::isRelativePathReference(new Uri('http://example.org')));
self::assertFalse(Uri::isRelativePathReference(new Uri('//example.org')));
self::assertFalse(Uri::isRelativePathReference(new Uri('/abs-path')));
self::assertTrue(Uri::isRelativePathReference(new Uri('rel-path')));
self::assertTrue(Uri::isRelativePathReference(new Uri('')));
}
public function testIsSameDocumentReference(): void
{
self::assertFalse(Uri::isSameDocumentReference(new Uri('http://example.org')));
self::assertFalse(Uri::isSameDocumentReference(new Uri('//example.org')));
self::assertFalse(Uri::isSameDocumentReference(new Uri('/abs-path')));
self::assertFalse(Uri::isSameDocumentReference(new Uri('rel-path')));
self::assertFalse(Uri::isSameDocumentReference(new Uri('?query')));
self::assertTrue(Uri::isSameDocumentReference(new Uri('')));
self::assertTrue(Uri::isSameDocumentReference(new Uri('#fragment')));
$baseUri = new Uri('http://example.org/path?foo=bar');
self::assertTrue(Uri::isSameDocumentReference(new Uri('#fragment'), $baseUri));
self::assertTrue(Uri::isSameDocumentReference(new Uri('?foo=bar#fragment'), $baseUri));
self::assertTrue(Uri::isSameDocumentReference(new Uri('/path?foo=bar#fragment'), $baseUri));
self::assertTrue(Uri::isSameDocumentReference(new Uri('path?foo=bar#fragment'), $baseUri));
self::assertTrue(Uri::isSameDocumentReference(new Uri('//example.org/path?foo=bar#fragment'), $baseUri));
self::assertTrue(Uri::isSameDocumentReference(new Uri('http://example.org/path?foo=bar#fragment'), $baseUri));
self::assertFalse(Uri::isSameDocumentReference(new Uri('https://example.org/path?foo=bar'), $baseUri));
self::assertFalse(Uri::isSameDocumentReference(new Uri('http://example.com/path?foo=bar'), $baseUri));
self::assertFalse(Uri::isSameDocumentReference(new Uri('http://example.org/'), $baseUri));
self::assertFalse(Uri::isSameDocumentReference(new Uri('http://example.org'), $baseUri));
self::assertFalse(Uri::isSameDocumentReference(new Uri('urn:/path'), new Uri('urn://example.com/path')));
}
public function testAddAndRemoveQueryValues(): void
{
$uri = new Uri();
$uri = Uri::withQueryValue($uri, 'a', 'b');
$uri = Uri::withQueryValue($uri, 'c', 'd');
$uri = Uri::withQueryValue($uri, 'e', null);
self::assertSame('a=b&c=d&e', $uri->getQuery());
$uri = Uri::withoutQueryValue($uri, 'c');
self::assertSame('a=b&e', $uri->getQuery());
$uri = Uri::withoutQueryValue($uri, 'e');
self::assertSame('a=b', $uri->getQuery());
$uri = Uri::withoutQueryValue($uri, 'a');
self::assertSame('', $uri->getQuery());
}
public function testScalarQueryValues(): void
{
$uri = new Uri();
$uri = Uri::withQueryValues($uri, [
2 => 2,
1 => true,
'false' => false,
'float' => 3.1,
]);
self::assertSame('2=2&1=1&false=&float=3.1', $uri->getQuery());
}
public function testWithQueryValues(): void
{
$uri = new Uri();
$uri = Uri::withQueryValues($uri, [
'key1' => 'value1',
'key2' => 'value2',
]);
self::assertSame('key1=value1&key2=value2', $uri->getQuery());
}
public function testWithQueryValuesReplacesSameKeys(): void
{
$uri = new Uri();
$uri = Uri::withQueryValues($uri, [
'key1' => 'value1',
'key2' => 'value2',
]);
$uri = Uri::withQueryValues($uri, [
'key2' => 'newvalue',
]);
self::assertSame('key1=value1&key2=newvalue', $uri->getQuery());
}
public function testWithQueryValueReplacesSameKeys(): void
{
$uri = new Uri();
$uri = Uri::withQueryValue($uri, 'a', 'b');
$uri = Uri::withQueryValue($uri, 'c', 'd');
$uri = Uri::withQueryValue($uri, 'a', 'e');
self::assertSame('c=d&a=e', $uri->getQuery());
}
public function testWithoutQueryValueRemovesAllSameKeys(): void
{
$uri = (new Uri())->withQuery('a=b&c=d&a=e');
$uri = Uri::withoutQueryValue($uri, 'a');
self::assertSame('c=d', $uri->getQuery());
}
public function testRemoveNonExistingQueryValue(): void
{
$uri = new Uri();
$uri = Uri::withQueryValue($uri, 'a', 'b');
$uri = Uri::withoutQueryValue($uri, 'c');
self::assertSame('a=b', $uri->getQuery());
}
public function testWithQueryValueHandlesEncoding(): void
{
$uri = new Uri();
$uri = Uri::withQueryValue($uri, 'E=mc^2', 'ein&stein');
self::assertSame('E%3Dmc%5E2=ein%26stein', $uri->getQuery(), 'Decoded key/value get encoded');
$uri = new Uri();
$uri = Uri::withQueryValue($uri, 'E%3Dmc%5e2', 'ein%26stein');
self::assertSame('E%3Dmc%5e2=ein%26stein', $uri->getQuery(), 'Encoded key/value do not get double-encoded');
}
public function testWithoutQueryValueHandlesEncoding(): void
{
// It also tests that the case of the percent-encoding does not matter,
// i.e. both lowercase "%3d" and uppercase "%5E" can be removed.
$uri = (new Uri())->withQuery('E%3dmc%5E2=einstein&foo=bar');
$uri = Uri::withoutQueryValue($uri, 'E=mc^2');
self::assertSame('foo=bar', $uri->getQuery(), 'Handles key in decoded form');
$uri = (new Uri())->withQuery('E%3dmc%5E2=einstein&foo=bar');
$uri = Uri::withoutQueryValue($uri, 'E%3Dmc%5e2');
self::assertSame('foo=bar', $uri->getQuery(), 'Handles key in encoded form');
}
public function testSchemeIsNormalizedToLowercase(): void
{
$uri = new Uri('HTTP://example.com');
self::assertSame('http', $uri->getScheme());
self::assertSame('http://example.com', (string) $uri);
$uri = (new Uri('//example.com'))->withScheme('HTTP');
self::assertSame('http', $uri->getScheme());
self::assertSame('http://example.com', (string) $uri);
}
public function testHostIsNormalizedToLowercase(): void
{
$uri = new Uri('//eXaMpLe.CoM');
self::assertSame('example.com', $uri->getHost());
self::assertSame('//example.com', (string) $uri);
$uri = (new Uri())->withHost('eXaMpLe.CoM');
self::assertSame('example.com', $uri->getHost());
self::assertSame('//example.com', (string) $uri);
}
public function testPortIsNullIfStandardPortForScheme(): void
{
// HTTPS standard port
$uri = new Uri('https://example.com:443');
self::assertNull($uri->getPort());
self::assertSame('example.com', $uri->getAuthority());
$uri = (new Uri('https://example.com'))->withPort(443);
self::assertNull($uri->getPort());
self::assertSame('example.com', $uri->getAuthority());
// HTTP standard port
$uri = new Uri('http://example.com:80');
self::assertNull($uri->getPort());
self::assertSame('example.com', $uri->getAuthority());
$uri = (new Uri('http://example.com'))->withPort(80);
self::assertNull($uri->getPort());
self::assertSame('example.com', $uri->getAuthority());
}
public function testPortIsReturnedIfSchemeUnknown(): void
{
$uri = (new Uri('//example.com'))->withPort(80);
self::assertSame(80, $uri->getPort());
self::assertSame('example.com:80', $uri->getAuthority());
}
public function testStandardPortIsNullIfSchemeChanges(): void
{
$uri = new Uri('http://example.com:443');
self::assertSame('http', $uri->getScheme());
self::assertSame(443, $uri->getPort());
$uri = $uri->withScheme('https');
self::assertNull($uri->getPort());
}
public function testPortPassedAsStringIsCastedToInt(): void
{
$uri = (new Uri('//example.com'))->withPort('8080');
self::assertSame(8080, $uri->getPort(), 'Port is returned as integer');
self::assertSame('example.com:8080', $uri->getAuthority());
}
public function testPortCanBeRemoved(): void
{
$uri = (new Uri('http://example.com:8080'))->withPort(null);
self::assertNull($uri->getPort());
self::assertSame('http://example.com', (string) $uri);
}
/**
* In RFC 8986 the host is optional and the authority can only
* consist of the user info and port.
*/
public function testAuthorityWithUserInfoOrPortButWithoutHost(): void
{
$uri = (new Uri())->withUserInfo('user', 'pass');
self::assertSame('user:pass', $uri->getUserInfo());
self::assertSame('user:pass@', $uri->getAuthority());
$uri = $uri->withPort(8080);
self::assertSame(8080, $uri->getPort());
self::assertSame('user:pass@:8080', $uri->getAuthority());
self::assertSame('//user:pass@:8080', (string) $uri);
$uri = $uri->withUserInfo('');
self::assertSame(':8080', $uri->getAuthority());
}
public function testHostInHttpUriDefaultsToLocalhost(): void
{
$uri = (new Uri())->withScheme('http');
self::assertSame('localhost', $uri->getHost());
self::assertSame('localhost', $uri->getAuthority());
self::assertSame('http://localhost', (string) $uri);
}
public function testHostInHttpsUriDefaultsToLocalhost(): void
{
$uri = (new Uri())->withScheme('https');
self::assertSame('localhost', $uri->getHost());
self::assertSame('localhost', $uri->getAuthority());
self::assertSame('https://localhost', (string) $uri);
}
public function testFileSchemeWithEmptyHostReconstruction(): void
{
$uri = new Uri('file:///tmp/filename.ext');
self::assertSame('', $uri->getHost());
self::assertSame('', $uri->getAuthority());
self::assertSame('file:///tmp/filename.ext', (string) $uri);
}
public function uriComponentsEncodingProvider(): iterable
{
$unreserved = 'a-zA-Z0-9.-_~!$&\'()*+,;=:@';
return [
// Percent encode spaces
['/pa th?q=va lue#frag ment', '/pa%20th', 'q=va%20lue', 'frag%20ment', '/pa%20th?q=va%20lue#frag%20ment'],
// Percent encode multibyte
['/€?€#€', '/%E2%82%AC', '%E2%82%AC', '%E2%82%AC', '/%E2%82%AC?%E2%82%AC#%E2%82%AC'],
// Don't encode something that's already encoded
['/pa%20th?q=va%20lue#frag%20ment', '/pa%20th', 'q=va%20lue', 'frag%20ment', '/pa%20th?q=va%20lue#frag%20ment'],
// Percent encode invalid percent encodings
['/pa%2-th?q=va%2-lue#frag%2-ment', '/pa%252-th', 'q=va%252-lue', 'frag%252-ment', '/pa%252-th?q=va%252-lue#frag%252-ment'],
// Don't encode path segments
['/pa/th//two?q=va/lue#frag/ment', '/pa/th//two', 'q=va/lue', 'frag/ment', '/pa/th//two?q=va/lue#frag/ment'],
// Don't encode unreserved chars or sub-delimiters
["/$unreserved?$unreserved#$unreserved", "/$unreserved", $unreserved, $unreserved, "/$unreserved?$unreserved#$unreserved"],
// Encoded unreserved chars are not decoded
['/p%61th?q=v%61lue#fr%61gment', '/p%61th', 'q=v%61lue', 'fr%61gment', '/p%61th?q=v%61lue#fr%61gment'],
];
}
/**
* @dataProvider uriComponentsEncodingProvider
*/
public function testUriComponentsGetEncodedProperly(string $input, string $path, string $query, string $fragment, string $output): void
{
$uri = new Uri($input);
self::assertSame($path, $uri->getPath());
self::assertSame($query, $uri->getQuery());
self::assertSame($fragment, $uri->getFragment());
self::assertSame($output, (string) $uri);
}
public function testWithPathEncodesProperly(): void
{
$uri = (new Uri())->withPath('/baz?#€/b%61r');
// Query and fragment delimiters and multibyte chars are encoded.
self::assertSame('/baz%3F%23%E2%82%AC/b%61r', $uri->getPath());
self::assertSame('/baz%3F%23%E2%82%AC/b%61r', (string) $uri);
}
public function testWithQueryEncodesProperly(): void
{
$uri = (new Uri())->withQuery('?=#&€=/&b%61r');
// A query starting with a "?" is valid and must not be magically removed. Otherwise it would be impossible to
// construct such an URI. Also the "?" and "/" does not need to be encoded in the query.
self::assertSame('?=%23&%E2%82%AC=/&b%61r', $uri->getQuery());
self::assertSame('??=%23&%E2%82%AC=/&b%61r', (string) $uri);
}
public function testWithFragmentEncodesProperly(): void
{
$uri = (new Uri())->withFragment('#€?/b%61r');
// A fragment starting with a "#" is valid and must not be magically removed. Otherwise it would be impossible to
// construct such an URI. Also the "?" and "/" does not need to be encoded in the fragment.
self::assertSame('%23%E2%82%AC?/b%61r', $uri->getFragment());
self::assertSame('#%23%E2%82%AC?/b%61r', (string) $uri);
}
public function testAllowsForRelativeUri(): void
{
$uri = (new Uri())->withPath('foo');
self::assertSame('foo', $uri->getPath());
self::assertSame('foo', (string) $uri);
}
public function testRelativePathAndAuthority(): void
{
$uri = (new Uri())->withHost('example.com')->withPath('foo');
self::assertSame('foo', $uri->getPath());
self::assertSame('//example.com/foo', $uri->__toString());
}
public function testPathStartingWithTwoSlashesAndNoAuthorityIsInvalid(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('The path of a URI without an authority must not start with two slashes "//"');
// URI "//foo" would be interpreted as network reference and thus change the original path to the host
(new Uri())->withPath('//foo');
}
public function testPathStartingWithTwoSlashes(): void
{
$uri = new Uri('http://example.org//path-not-host.com');
self::assertSame('//path-not-host.com', $uri->getPath());
$uri = $uri->withScheme('');
self::assertSame('//example.org//path-not-host.com', (string) $uri); // This is still valid
$this->expectException(\InvalidArgumentException::class);
$uri->withHost(''); // Now it becomes invalid
}
public function testRelativeUriWithPathBeginngWithColonSegmentIsInvalid(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('A relative URI must not have a path beginning with a segment containing a colon');
(new Uri())->withPath('mailto:foo');
}
public function testRelativeUriWithPathHavingColonSegment(): void
{
$uri = (new Uri('urn:/mailto:foo'))->withScheme('');
self::assertSame('/mailto:foo', $uri->getPath());
$this->expectException(\InvalidArgumentException::class);
(new Uri('urn:mailto:foo'))->withScheme('');
}
public function testDefaultReturnValuesOfGetters(): void
{
$uri = new Uri();
self::assertSame('', $uri->getScheme());
self::assertSame('', $uri->getAuthority());
self::assertSame('', $uri->getUserInfo());
self::assertSame('', $uri->getHost());
self::assertNull($uri->getPort());
self::assertSame('', $uri->getPath());
self::assertSame('', $uri->getQuery());
self::assertSame('', $uri->getFragment());
}
public function testImmutability(): void
{
$uri = new Uri();
self::assertNotSame($uri, $uri->withScheme('https'));
self::assertNotSame($uri, $uri->withUserInfo('user', 'pass'));
self::assertNotSame($uri, $uri->withHost('example.com'));
self::assertNotSame($uri, $uri->withPort(8080));
self::assertNotSame($uri, $uri->withPath('/path/123'));
self::assertNotSame($uri, $uri->withQuery('q=abc'));
self::assertNotSame($uri, $uri->withFragment('test'));
}
public function testExtendingClassesInstantiates(): void
{
// The non-standard port triggers a cascade of private methods which
// should not use late static binding to access private static members.
// If they do, this will fatal.
self::assertInstanceOf(
ExtendedUriTest::class,
new ExtendedUriTest('http://h:9/')
);
}
public function testSpecialCharsOfUserInfo(): void
{
// The `userInfo` must always be URL-encoded.
$uri = (new Uri())->withUserInfo('foo@bar.com', 'pass#word');
self::assertSame('foo%40bar.com:pass%23word', $uri->getUserInfo());
// The `userInfo` can already be URL-encoded: it should not be encoded twice.
$uri = (new Uri())->withUserInfo('foo%40bar.com', 'pass%23word');
self::assertSame('foo%40bar.com:pass%23word', $uri->getUserInfo());
}
public function testInternationalizedDomainName(): void
{
$uri = new Uri('https://яндекс.рф');
self::assertSame('яндекс.рф', $uri->getHost());
$uri = new Uri('https://яндекAс.рф');
self::assertSame('яндекaс.рф', $uri->getHost());
}
public function testIPv6Host(): void
{
$uri = new Uri('https://[2a00:f48:1008::212:183:10]');
self::assertSame('[2a00:f48:1008::212:183:10]', $uri->getHost());
$uri = new Uri('http://[2a00:f48:1008::212:183:10]:56?foo=bar');
self::assertSame('[2a00:f48:1008::212:183:10]', $uri->getHost());
self::assertSame(56, $uri->getPort());
self::assertSame('foo=bar', $uri->getQuery());
}
public function testJsonSerializable(): void
{
$uri = new Uri('https://example.com');
self::assertSame('{"uri":"https:\/\/example.com"}', \json_encode(['uri' => $uri]));
}
}
class ExtendedUriTest extends Uri
{
}

551
vendor/guzzlehttp/psr7/tests/UtilsTest.php

@ -1,551 +0,0 @@
<?php
declare(strict_types=1);
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\FnStream;
use GuzzleHttp\Psr7\NoSeekStream;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\StreamInterface;
class UtilsTest extends TestCase
{
public function testCopiesToString(): void
{
$s = Psr7\Utils::streamFor('foobaz');
self::assertSame('foobaz', Psr7\Utils::copyToString($s));
$s->seek(0);
self::assertSame('foo', Psr7\Utils::copyToString($s, 3));
self::assertSame('baz', Psr7\Utils::copyToString($s, 3));
self::assertSame('', Psr7\Utils::copyToString($s));
}
public function testCopiesToStringStopsWhenReadFails(): void
{
$s1 = Psr7\Utils::streamFor('foobaz');
$s1 = FnStream::decorate($s1, [
'read' => function () {
return '';
},
]);
$result = Psr7\Utils::copyToString($s1);
self::assertSame('', $result);
}
public function testCopiesToStream(): void
{
$s1 = Psr7\Utils::streamFor('foobaz');
$s2 = Psr7\Utils::streamFor('');
Psr7\Utils::copyToStream($s1, $s2);
self::assertSame('foobaz', (string) $s2);
$s2 = Psr7\Utils::streamFor('');
$s1->seek(0);
Psr7\Utils::copyToStream($s1, $s2, 3);
self::assertSame('foo', (string) $s2);
Psr7\Utils::copyToStream($s1, $s2, 3);
self::assertSame('foobaz', (string) $s2);
}
public function testStopsCopyToStreamWhenWriteFails(): void
{
$s1 = Psr7\Utils::streamFor('foobaz');
$s2 = Psr7\Utils::streamFor('');
$s2 = FnStream::decorate($s2, [
'write' => function () {
return 0;
},
]);
Psr7\Utils::copyToStream($s1, $s2);
self::assertSame('', (string) $s2);
}
public function testStopsCopyToSteamWhenWriteFailsWithMaxLen(): void
{
$s1 = Psr7\Utils::streamFor('foobaz');
$s2 = Psr7\Utils::streamFor('');
$s2 = FnStream::decorate($s2, [
'write' => function () {
return 0;
},
]);
Psr7\Utils::copyToStream($s1, $s2, 10);
self::assertSame('', (string) $s2);
}
public function testCopyToStreamReadsInChunksInsteadOfAllInMemory(): void
{
$sizes = [];
$s1 = new FnStream([
'eof' => function () {
return false;
},
'read' => function ($size) use (&$sizes) {
$sizes[] = $size;
return str_repeat('.', $size);
},
]);
$s2 = Psr7\Utils::streamFor('');
Psr7\Utils::copyToStream($s1, $s2, 16394);
$s2->seek(0);
self::assertSame(16394, strlen($s2->getContents()));
self::assertSame(8192, $sizes[0]);
self::assertSame(8192, $sizes[1]);
self::assertSame(10, $sizes[2]);
}
public function testStopsCopyToSteamWhenReadFailsWithMaxLen(): void
{
$s1 = Psr7\Utils::streamFor('foobaz');
$s1 = FnStream::decorate($s1, [
'read' => function () {
return '';
},
]);
$s2 = Psr7\Utils::streamFor('');
Psr7\Utils::copyToStream($s1, $s2, 10);
self::assertSame('', (string) $s2);
}
public function testReadsLines(): void
{
$s = Psr7\Utils::streamFor("foo\nbaz\nbar");
self::assertSame("foo\n", Psr7\Utils::readLine($s));
self::assertSame("baz\n", Psr7\Utils::readLine($s));
self::assertSame('bar', Psr7\Utils::readLine($s));
}
public function testReadsLinesUpToMaxLength(): void
{
$s = Psr7\Utils::streamFor("12345\n");
self::assertSame('123', Psr7\Utils::readLine($s, 4));
self::assertSame("45\n", Psr7\Utils::readLine($s));
}
public function testReadLinesEof(): void
{
// Should return empty string on EOF
$s = Psr7\Utils::streamFor("foo\nbar");
while (!$s->eof()) {
Psr7\Utils::readLine($s);
}
self::assertSame('', Psr7\Utils::readLine($s));
}
public function testReadsLineUntilEmptyStringReturnedFromRead(): void
{
$s = $this->createMock(StreamInterface::class);
$s->expects(self::exactly(2))
->method('read')
->willReturnCallback(function () {
static $called = false;
if ($called) {
return '';
}
$called = true;
return 'h';
});
$s->expects(self::exactly(2))
->method('eof')
->willReturn(false);
self::assertSame('h', Psr7\Utils::readLine($s));
}
public function testRedactUserInfo(): void
{
$uri = new Psr7\Uri('http://my_user:secretPass@localhost/');
$redactedUri = Psr7\Utils::redactUserInfo($uri);
self::assertSame('http://my_user:***@localhost/', (string) $redactedUri);
}
public function testCalculatesHash(): void
{
$s = Psr7\Utils::streamFor('foobazbar');
self::assertSame(md5('foobazbar'), Psr7\Utils::hash($s, 'md5'));
}
public function testCalculatesHashThrowsWhenSeekFails(): void
{
$s = new NoSeekStream(Psr7\Utils::streamFor('foobazbar'));
$s->read(2);
$this->expectException(\RuntimeException::class);
Psr7\Utils::hash($s, 'md5');
}
public function testCalculatesHashSeeksToOriginalPosition(): void
{
$s = Psr7\Utils::streamFor('foobazbar');
$s->seek(4);
self::assertSame(md5('foobazbar'), Psr7\Utils::hash($s, 'md5'));
self::assertSame(4, $s->tell());
}
public function testOpensFilesSuccessfully(): void
{
$r = Psr7\Utils::tryFopen(__FILE__, 'r');
self::assertIsResource($r);
fclose($r);
}
public function testThrowsExceptionNotWarning(): void
{
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('Unable to open "/path/to/does/not/exist" using mode "r"');
Psr7\Utils::tryFopen('/path/to/does/not/exist', 'r');
}
public function testThrowsExceptionNotValueError(): void
{
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('Unable to open "" using mode "r"');
Psr7\Utils::tryFopen('', 'r');
}
/**
* @requires PHP 7.4
*/
public function testGetsContentsThrowExceptionWhenNotReadable(): void
{
$r = fopen(tempnam(sys_get_temp_dir(), 'guzzle-psr7-'), 'w');
fwrite($r, 'hello world!');
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('Unable to read stream contents');
try {
Psr7\Utils::tryGetContents($r);
} finally {
fclose($r);
}
}
public function testGetsContentsThrowExceptionWhenCLosed(): void
{
$r = fopen(tempnam(sys_get_temp_dir(), 'guzzle-psr7-'), 'r+');
fclose($r);
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('Unable to read stream contents');
Psr7\Utils::tryGetContents($r);
}
public function testCreatesUriForValue(): void
{
self::assertInstanceOf('GuzzleHttp\Psr7\Uri', Psr7\Utils::uriFor('/foo'));
self::assertInstanceOf(
'GuzzleHttp\Psr7\Uri',
Psr7\Utils::uriFor(new Psr7\Uri('/foo'))
);
}
public function testValidatesUri(): void
{
$this->expectException(\InvalidArgumentException::class);
Psr7\Utils::uriFor([]);
}
public function testKeepsPositionOfResource(): void
{
$h = fopen(__FILE__, 'r');
fseek($h, 10);
$stream = Psr7\Utils::streamFor($h);
self::assertSame(10, $stream->tell());
$stream->close();
}
public function testCreatesWithFactory(): void
{
$stream = Psr7\Utils::streamFor('foo');
self::assertInstanceOf('GuzzleHttp\Psr7\Stream', $stream);
self::assertSame('foo', $stream->getContents());
$stream->close();
}
public function testFactoryCreatesFromEmptyString(): void
{
$s = Psr7\Utils::streamFor();
self::assertInstanceOf('GuzzleHttp\Psr7\Stream', $s);
}
public function testFactoryCreatesFromNull(): void
{
$s = Psr7\Utils::streamFor(null);
self::assertInstanceOf('GuzzleHttp\Psr7\Stream', $s);
}
public function testFactoryCreatesFromResource(): void
{
$r = fopen(__FILE__, 'r');
$s = Psr7\Utils::streamFor($r);
self::assertInstanceOf('GuzzleHttp\Psr7\Stream', $s);
self::assertSame(file_get_contents(__FILE__), (string) $s);
}
public function testFactoryCreatesFromObjectWithToString(): void
{
$r = new HasToString();
$s = Psr7\Utils::streamFor($r);
self::assertInstanceOf('GuzzleHttp\Psr7\Stream', $s);
self::assertSame('foo', (string) $s);
}
public function testCreatePassesThrough(): void
{
$s = Psr7\Utils::streamFor('foo');
self::assertSame($s, Psr7\Utils::streamFor($s));
}
public function testThrowsExceptionForUnknown(): void
{
$this->expectException(\InvalidArgumentException::class);
Psr7\Utils::streamFor(new \stdClass());
}
public function testReturnsCustomMetadata(): void
{
$s = Psr7\Utils::streamFor('foo', ['metadata' => ['hwm' => 3]]);
self::assertSame(3, $s->getMetadata('hwm'));
self::assertArrayHasKey('hwm', $s->getMetadata());
}
public function testCanSetSize(): void
{
$s = Psr7\Utils::streamFor('', ['size' => 10]);
self::assertSame(10, $s->getSize());
}
public function testCanCreateIteratorBasedStream(): void
{
$a = new \ArrayIterator(['foo', 'bar', '123']);
$p = Psr7\Utils::streamFor($a);
self::assertInstanceOf('GuzzleHttp\Psr7\PumpStream', $p);
self::assertSame('foo', $p->read(3));
self::assertFalse($p->eof());
self::assertSame('b', $p->read(1));
self::assertSame('a', $p->read(1));
self::assertSame('r12', $p->read(3));
self::assertFalse($p->eof());
self::assertSame('3', $p->getContents());
self::assertTrue($p->eof());
self::assertSame(9, $p->tell());
}
public function testConvertsRequestsToStrings(): void
{
$request = new Psr7\Request('PUT', 'http://foo.com/hi?123', [
'Baz' => 'bar',
'Qux' => 'ipsum',
], 'hello', '1.0');
self::assertSame(
"PUT /hi?123 HTTP/1.0\r\nHost: foo.com\r\nBaz: bar\r\nQux: ipsum\r\n\r\nhello",
Psr7\Message::toString($request)
);
}
public function testConvertsResponsesToStrings(): void
{
$response = new Psr7\Response(200, [
'Baz' => 'bar',
'Qux' => 'ipsum',
], 'hello', '1.0', 'FOO');
self::assertSame(
"HTTP/1.0 200 FOO\r\nBaz: bar\r\nQux: ipsum\r\n\r\nhello",
Psr7\Message::toString($response)
);
}
public function testCorrectlyRendersSetCookieHeadersToString(): void
{
$response = new Psr7\Response(200, [
'Set-Cookie' => ['bar', 'baz', 'qux'],
], 'hello', '1.0', 'FOO');
self::assertSame(
"HTTP/1.0 200 FOO\r\nSet-Cookie: bar\r\nSet-Cookie: baz\r\nSet-Cookie: qux\r\n\r\nhello",
Psr7\Message::toString($response)
);
}
public function testCanModifyRequestWithUri(): void
{
$r1 = new Psr7\Request('GET', 'http://foo.com');
$r2 = Psr7\Utils::modifyRequest($r1, [
'uri' => new Psr7\Uri('http://www.foo.com'),
]);
self::assertSame('http://www.foo.com', (string) $r2->getUri());
self::assertSame('www.foo.com', (string) $r2->getHeaderLine('host'));
}
public function testCanModifyRequestWithUriAndPort(): void
{
$r1 = new Psr7\Request('GET', 'http://foo.com:8000');
$r2 = Psr7\Utils::modifyRequest($r1, [
'uri' => new Psr7\Uri('http://www.foo.com:8000'),
]);
self::assertSame('http://www.foo.com:8000', (string) $r2->getUri());
self::assertSame('www.foo.com:8000', (string) $r2->getHeaderLine('host'));
}
public function testCanModifyRequestWithCaseInsensitiveHeader(): void
{
$r1 = new Psr7\Request('GET', 'http://foo.com', ['User-Agent' => 'foo']);
$r2 = Psr7\Utils::modifyRequest($r1, ['set_headers' => ['User-agent' => 'bar']]);
self::assertSame('bar', $r2->getHeaderLine('User-Agent'));
self::assertSame('bar', $r2->getHeaderLine('User-agent'));
}
public function testReturnsAsIsWhenNoChanges(): void
{
$r1 = new Psr7\Request('GET', 'http://foo.com');
$r2 = Psr7\Utils::modifyRequest($r1, []);
self::assertInstanceOf('GuzzleHttp\Psr7\Request', $r2);
$r1 = new Psr7\ServerRequest('GET', 'http://foo.com');
$r2 = Psr7\Utils::modifyRequest($r1, []);
self::assertInstanceOf('Psr\Http\Message\ServerRequestInterface', $r2);
}
public function testReturnsUriAsIsWhenNoChanges(): void
{
$r1 = new Psr7\Request('GET', 'http://foo.com');
$r2 = Psr7\Utils::modifyRequest($r1, ['set_headers' => ['foo' => 'bar']]);
self::assertNotSame($r1, $r2);
self::assertSame('bar', $r2->getHeaderLine('foo'));
}
public function testRemovesHeadersFromMessage(): void
{
$r1 = new Psr7\Request('GET', 'http://foo.com', ['foo' => 'bar']);
$r2 = Psr7\Utils::modifyRequest($r1, ['remove_headers' => ['foo']]);
self::assertNotSame($r1, $r2);
self::assertFalse($r2->hasHeader('foo'));
}
public function testAddsQueryToUri(): void
{
$r1 = new Psr7\Request('GET', 'http://foo.com');
$r2 = Psr7\Utils::modifyRequest($r1, ['query' => 'foo=bar']);
self::assertNotSame($r1, $r2);
self::assertSame('foo=bar', $r2->getUri()->getQuery());
}
public function testModifyRequestKeepInstanceOfRequest(): void
{
$r1 = new Psr7\Request('GET', 'http://foo.com');
$r2 = Psr7\Utils::modifyRequest($r1, ['remove_headers' => ['non-existent']]);
self::assertInstanceOf('GuzzleHttp\Psr7\Request', $r2);
$r1 = new Psr7\ServerRequest('GET', 'http://foo.com');
$r2 = Psr7\Utils::modifyRequest($r1, ['remove_headers' => ['non-existent']]);
self::assertInstanceOf('Psr\Http\Message\ServerRequestInterface', $r2);
}
public function testModifyServerRequestWithUploadedFiles(): void
{
$request = new Psr7\ServerRequest('GET', 'http://example.com/bla');
$file = new Psr7\UploadedFile('Test', 100, \UPLOAD_ERR_OK);
$request = $request->withUploadedFiles([$file]);
/** @var Psr7\ServerRequest $modifiedRequest */
$modifiedRequest = Psr7\Utils::modifyRequest($request, ['set_headers' => ['foo' => 'bar']]);
self::assertCount(1, $modifiedRequest->getUploadedFiles());
$files = $modifiedRequest->getUploadedFiles();
self::assertInstanceOf('GuzzleHttp\Psr7\UploadedFile', $files[0]);
}
public function testModifyServerRequestWithCookies(): void
{
$request = (new Psr7\ServerRequest('GET', 'http://example.com/bla'))
->withCookieParams(['name' => 'value']);
/** @var Psr7\ServerRequest $modifiedRequest */
$modifiedRequest = Psr7\Utils::modifyRequest($request, ['set_headers' => ['foo' => 'bar']]);
self::assertSame(['name' => 'value'], $modifiedRequest->getCookieParams());
}
public function testModifyServerRequestParsedBody(): void
{
$request = (new Psr7\ServerRequest('GET', 'http://example.com/bla'))
->withParsedBody(['name' => 'value']);
/** @var Psr7\ServerRequest $modifiedRequest */
$modifiedRequest = Psr7\Utils::modifyRequest($request, ['set_headers' => ['foo' => 'bar']]);
self::assertSame(['name' => 'value'], $modifiedRequest->getParsedBody());
}
public function testModifyServerRequestQueryParams(): void
{
$request = (new Psr7\ServerRequest('GET', 'http://example.com/bla'))
->withQueryParams(['name' => 'value']);
/** @var Psr7\ServerRequest $modifiedRequest */
$modifiedRequest = Psr7\Utils::modifyRequest($request, ['set_headers' => ['foo' => 'bar']]);
self::assertSame(['name' => 'value'], $modifiedRequest->getQueryParams());
}
public function testModifyServerRequestRetainsAttributes(): void
{
$request = (new Psr7\ServerRequest('GET', 'http://example.com/bla'))
->withAttribute('foo', 'bar');
/** @var Psr7\ServerRequest $modifiedRequest */
$modifiedRequest = Psr7\Utils::modifyRequest($request, []);
self::assertSame(['foo' => 'bar'], $modifiedRequest->getAttributes());
}
/**
* @return list<array{0: string[], 1: array, 2: array}>
*/
public function providesCaselessRemoveCases(): array
{
return [
[
['foo-bar'],
['Foo-Bar' => 'hello'],
[],
],
[
['foo-bar'],
['hello'],
['hello'],
],
[
['foo-Bar'],
['Foo-Bar' => 'hello', 123 => '', 'Foo-BAR' => 'hello123', 'foobar' => 'baz'],
[123 => '', 'foobar' => 'baz'],
],
[
['foo-Bar', 123],
['Foo-Bar' => 'hello', 123 => '', 'Foo-BAR' => 'hello123', 'foobar' => 'baz'],
['foobar' => 'baz'],
],
];
}
/**
* @dataProvider providesCaselessRemoveCases
*
* @param string[] $keys
*/
public function testCaselessRemove(array $keys, array $data, array $expected): void
{
self::assertSame($expected, Psr7\Utils::caselessRemove($keys, $data));
}
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save