Passed
Pull Request — master (#25)
by Sergei
02:30
created

TestApplicationRunner::withRequest()   A

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