TestApplicationRunner::withRequest()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 23
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 12
c 2
b 0
f 0
nc 1
nop 8
dl 0
loc 23
ccs 0
cts 14
cp 0
crap 2
rs 9.8666

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Testing;
6
7
use Psr\Container\ContainerInterface;
8
use Psr\Http\Message\ResponseInterface;
9
use Psr\Http\Message\ServerRequestFactoryInterface;
10
use Psr\Http\Message\ServerRequestInterface;
11
use Throwable;
12
use Yiisoft\Config\ConfigInterface;
13
use Yiisoft\Di\Container;
14
use Yiisoft\Di\ContainerConfig;
15
use Yiisoft\Di\ServiceProviderInterface;
16
use Yiisoft\ErrorHandler\ErrorHandler;
0 ignored issues
show
Bug introduced by
The type Yiisoft\ErrorHandler\ErrorHandler was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use Yiisoft\ErrorHandler\Middleware\ErrorCatcher;
18
use Yiisoft\Yii\Http\Application;
19
use Yiisoft\Yii\Http\Handler\ThrowableHandler;
20
use Yiisoft\Yii\Runner\ApplicationRunner;
21
22
final class TestApplicationRunner extends ApplicationRunner
23
{
24
    public ?ContainerInterface $container = null;
25
    private array $requestParameters = [];
26
    /**
27
     * @var ServiceProviderInterface[]
28
     */
29
    private array $providers = [];
30
31
    /**
32
     * @param string $rootPath The absolute path to the project root.
33
     * @param bool $debug Whether the debug mode is enabled.
34
     * @param bool $checkEvents Whether to check events' configuration.
35
     * @param string|null $environment The environment name.
36
     * @param string $bootstrapGroup The bootstrap configuration group name.
37
     * @param string $eventsGroup The events' configuration group name.
38
     * @param string $diGroup The container definitions' configuration group name.
39
     * @param string $diProvidersGroup The container providers' configuration group name.
40
     * @param string $diDelegatesGroup The container delegates' configuration group name.
41
     * @param string $diTagsGroup The container tags' configuration group name.
42
     * @param string $paramsGroup The configuration parameters group name.
43
     * @param array $nestedParamsGroups Configuration group names that included into configuration parameters group.
44
     * This is needed for recursive merging of parameters.
45
     * @param array $nestedEventsGroups Configuration group names that included into events' configuration group. This
46
     * is needed for reverse and recursive merge of events' configurations.
47
     *
48
     * @psalm-param list<string> $nestedParamsGroups
49
     * @psalm-param list<string> $nestedEventsGroups
50
     */
51
    public function __construct(
52
        public ResponseGrabber $responseGrabber,
53
        string $rootPath,
54
        bool $debug = false,
55
        bool $checkEvents = false,
56
        ?string $environment = null,
57
        string $bootstrapGroup = 'bootstrap-web',
58
        string $eventsGroup = 'events-web',
59
        string $diGroup = 'di-web',
60
        string $diProvidersGroup = 'di-providers-web',
61
        string $diDelegatesGroup = 'di-delegates-web',
62
        string $diTagsGroup = 'di-tags-web',
63
        string $paramsGroup = 'params-web',
64
        array $nestedParamsGroups = ['params'],
65
        array $nestedEventsGroups = ['events'],
66
    ) {
67
        parent::__construct(
68
            $rootPath,
69
            $debug,
70
            $checkEvents,
71
            $environment,
72
            $bootstrapGroup,
73
            $eventsGroup,
74
            $diGroup,
75
            $diProvidersGroup,
76
            $diDelegatesGroup,
77
            $diTagsGroup,
78
            $paramsGroup,
79
            $nestedParamsGroups,
80
            $nestedEventsGroups,
81
        );
82
    }
83
84
    /**
85
     * {@inheritDoc}
86
     */
87
    public function run(): void
88
    {
89
        $this->preloadContainer();
90
91
        /** @var ContainerInterface $container */
92
        $container = $this->container;
93
94
        $errorHandler = $container->get(ErrorHandler::class);
95
        if ($this->debug) {
96
            $errorHandler->debug();
97
        }
98
        $errorHandler->register();
99
100
        /** @var Application $application */
101
        $application = $container->get(Application::class);
102
103
        /**
104
         * @var ServerRequestInterface
105
         * @psalm-suppress MixedMethodCall
106
         */
107
        $serverRequest = $container
108
            ->get(ServerRequestFactoryInterface::class)
109
            ->createServerRequest(
110
                $this->requestParameters['server']['REQUEST_METHOD'],
111
                $this->requestParameters['server']['REQUEST_URI'],
112
            );
113
114
        /**
115
         * @var ResponseInterface|null $response
116
         */
117
        $response = null;
118
        try {
119
            $application->start();
120
            $response = $application->handle($serverRequest);
121
        } catch (Throwable $throwable) {
122
            $handler = new ThrowableHandler($throwable);
123
            /**
124
             * @psalm-suppress MixedMethodCall
125
             */
126
            $response = $container
127
                ->get(ErrorCatcher::class)
128
                ->process($serverRequest, $handler);
129
        } finally {
130
            $application->afterEmit($response ?? null);
131
            $application->shutdown();
132
            $this->responseGrabber->setResponse($response);
133
        }
134
    }
135
136
    public function withRequest(
137
        string $method,
138
        string $url,
139
        array $queryParams = [],
140
        array $postParams = [],
141
        mixed $body = null,
142
        array $headers = [],
143
        array $cookies = [],
144
        array $files = [],
145
    ): void {
146
        $this->requestParameters = [
147
            'server' => [
148
                'SCRIPT_NAME' => '/index.php',
149
                'REQUEST_METHOD' => $method,
150
                'SERVER_PROTOCOL' => '1.1',
151
                'REQUEST_URI' => $url,
152
            ],
153
            'headers' => $headers,
154
            'cookies' => $cookies,
155
            'get' => $queryParams,
156
            'post' => $postParams,
157
            'files' => $files,
158
            'body' => $body,
159
        ];
160
    }
161
162
    public function preloadContainer(): void
163
    {
164
        /**
165
         * @psalm-suppress UnresolvableInclude
166
         */
167
        require_once $this->rootPath . '/autoload.php';
168
169
        $this->container = $this->createContainer();
170
171
        $this->runBootstrap();
172
        $this->checkEvents();
173
    }
174
175
    /**
176
     * @param ServiceProviderInterface[] $providers
177
     */
178
    public function addProviders(array $providers): void
179
    {
180
        $this->providers = array_merge($this->providers, $providers);
181
    }
182
183
    private function createContainer(): Container
184
    {
185
        $containerConfig = ContainerConfig::create()->withValidate($this->debug);
186
187
        $config = $this->getConfig();
188
189
        if (null !== $definitions = $this->getConfiguration($this->diGroup)) {
190
            $containerConfig = $containerConfig->withDefinitions($definitions);
191
        }
192
193
        if (null !== $providers = $this->getConfiguration($this->diProvidersGroup)) {
194
            $providers = array_merge($providers, $this->providers);
195
        } else {
196
            $providers = $this->providers;
197
        }
198
        $containerConfig = $containerConfig->withProviders($providers);
199
200
        if (null !== $delegates = $this->getConfiguration($this->diDelegatesGroup)) {
201
            $containerConfig = $containerConfig->withDelegates($delegates);
202
        }
203
204
        if (null !== $tags = $this->getConfiguration($this->diTagsGroup)) {
205
            $containerConfig = $containerConfig->withTags($tags);
206
        }
207
208
        $containerConfig = $containerConfig->withDefinitions(
209
            array_merge($containerConfig->getDefinitions(), [ConfigInterface::class => $config])
210
        );
211
212
        return new Container($containerConfig);
213
    }
214
}
215