Passed
Push — master ( bace86...bb4cad )
by Dmitriy
05:30 queued 02:57
created

dataSkipCollectOnMatchIgnoreReferences()   C

Complexity

Conditions 10
Paths 1

Size

Total Lines 241
Code Lines 147

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 147
nc 1
nop 0
dl 0
loc 241
rs 6.1333
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Debug\Tests\Unit\Collector;
6
7
use Yiisoft\Files\FileHelper;
8
use Yiisoft\Yii\Debug\Collector\CollectorInterface;
9
use Yiisoft\Yii\Debug\Collector\Stream\FilesystemStreamCollector;
10
use Yiisoft\Yii\Debug\Tests\Shared\AbstractCollectorTestCase;
11
12
final class FilesystemStreamCollectorTest extends AbstractCollectorTestCase
13
{
14
    /**
15
     * @param FilesystemStreamCollector $collector
16
     */
17
    protected function collectTestData(CollectorInterface $collector): void
18
    {
19
        $collector->collect(
0 ignored issues
show
Bug introduced by
The method collect() does not exist on Yiisoft\Yii\Debug\Collector\CollectorInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Yiisoft\Yii\Debug\Collec...mmaryCollectorInterface or Yiisoft\Yii\Debug\Tests\...\Support\DummyCollector. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

19
        $collector->/** @scrutinizer ignore-call */ 
20
                    collect(
Loading history...
20
            operation: 'read',
21
            path: __FILE__,
22
            args: ['arg1' => 'v1', 'arg2' => 'v2'],
23
        );
24
        $collector->collect(
25
            operation: 'read',
26
            path: __FILE__,
27
            args: ['arg3' => 'v3', 'arg4' => 'v4'],
28
        );
29
        $collector->collect(
30
            operation: 'mkdir',
31
            path: __DIR__,
32
            args: ['recursive'],
33
        );
34
    }
35
36
    /**
37
     * @dataProvider dataSkipCollectOnMatchIgnoreReferences
38
     */
39
    public function testSkipCollectOnMatchIgnoreReferences(
40
        string $path,
41
        callable $before,
42
        array $ignoredPathPatterns,
43
        array $ignoredClasses,
44
        callable $operation,
45
        callable $after,
46
        array $result,
47
    ): void {
48
        $before($path);
49
50
        try {
51
            $collector = new FilesystemStreamCollector(
52
                ignoredPathPatterns: $ignoredPathPatterns,
53
                ignoredClasses: $ignoredClasses,
54
            );
55
            $collector->startup();
56
57
            $operation($path);
58
59
            $collected = $collector->getCollected();
60
            $collector->shutdown();
61
        } finally {
62
            $after($path);
63
        }
64
        $this->assertEquals($result, $collected);
65
    }
66
67
    public function dataSkipCollectOnMatchIgnoreReferences(): iterable
68
    {
69
        $mkdirBefore = function (string $path) {
70
            if (is_dir($path)) {
71
                @rmdir($path);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for rmdir(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

71
                /** @scrutinizer ignore-unhandled */ @rmdir($path);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
72
            }
73
        };
74
        $mkdirOperation = function (string $path) {
75
            mkdir($path, 0777, true);
76
        };
77
        $mkdirAfter = $mkdirBefore;
78
79
        yield 'mkdir matched' => [
80
            $path = __DIR__ . DIRECTORY_SEPARATOR . 'stub' . DIRECTORY_SEPARATOR . 'internal',
81
            $mkdirBefore,
82
            [],
83
            [],
84
            $mkdirOperation,
85
            $mkdirAfter,
86
            [
87
                'mkdir' => [
88
                    ['path' => $path, 'args' => ['mode' => 0777, 'options' => 9]], // 9 for some reasons
89
                ],
90
            ],
91
        ];
92
        yield 'mkdir ignored by path' => [
93
            $path,
94
            $mkdirBefore,
95
            ['/' . basename(__FILE__, '.php') . '/'],
96
            [],
97
            $mkdirOperation,
98
            $mkdirAfter,
99
            [],
100
        ];
101
        yield 'mkdir ignored by class' => [
102
            $path,
103
            $mkdirBefore,
104
            [],
105
            [self::class],
106
            $mkdirOperation,
107
            $mkdirAfter,
108
            [],
109
        ];
110
111
        $renameBefore = function (string $path) {
112
            if (!is_dir(dirname($path))) {
113
                mkdir(dirname($path), 0777, true);
114
            }
115
            if (!is_file($path)) {
116
                touch($path);
117
            }
118
        };
119
        $renameOperation = function (string $path) {
120
            rename($path, $path . '.renamed');
121
        };
122
        $renameAfter = function (string $path) {
123
            FileHelper::removeDirectory(dirname($path));
124
        };
125
126
        yield 'rename matched' => [
127
            $path = __DIR__ . DIRECTORY_SEPARATOR . 'stub' . DIRECTORY_SEPARATOR . 'file-to-rename.txt',
128
            $renameBefore,
129
            [],
130
            [],
131
            $renameOperation,
132
            $renameAfter,
133
            [
134
                'rename' => [
135
                    ['path' => $path, 'args' => ['path_to' => $path . '.renamed']],
136
                ],
137
            ],
138
        ];
139
        yield 'rename ignored by path' => [
140
            $path,
141
            $renameBefore,
142
            ['/' . basename(__FILE__, '.php') . '/'],
143
            [],
144
            $renameOperation,
145
            $renameAfter,
146
            [],
147
        ];
148
        yield 'rename ignored by class' => [
149
            $path,
150
            $renameBefore,
151
            [],
152
            [self::class],
153
            $renameOperation,
154
            $renameAfter,
155
            [],
156
        ];
157
158
        $rmdirBefore = function (string $path) {
159
            if (!is_dir($path)) {
160
                mkdir($path, 0777, true);
161
            }
162
        };
163
        $rmdirOperation = function (string $path) {
164
            rmdir($path);
165
        };
166
        $rmdirAfter = function (string $path) {
167
            if (is_dir($path)) {
168
                rmdir($path);
169
            }
170
        };
171
172
        yield 'rmdir matched' => [
173
            $path = __DIR__ . DIRECTORY_SEPARATOR . 'stub' . DIRECTORY_SEPARATOR . 'dir-to-remove',
174
            $rmdirBefore,
175
            [],
176
            [],
177
            $rmdirOperation,
178
            $rmdirAfter,
179
            [
180
                'rmdir' => [
181
                    ['path' => $path, 'args' => ['options' => 8]], // 8 for some reasons
182
                ],
183
            ],
184
        ];
185
        yield 'rmdir ignored by path' => [
186
            $path,
187
            $rmdirBefore,
188
            ['/' . basename(__FILE__, '.php') . '/'],
189
            [],
190
            $rmdirOperation,
191
            $rmdirAfter,
192
            [],
193
        ];
194
        yield 'rmdir ignored by class' => [
195
            $path,
196
            $rmdirBefore,
197
            [],
198
            [self::class],
199
            $rmdirOperation,
200
            $rmdirAfter,
201
            [],
202
        ];
203
204
        $unlinkBefore = function (string $path) {
205
            if (!is_dir(dirname($path))) {
206
                mkdir(dirname($path), 0777, true);
207
            }
208
            if (!is_file($path)) {
209
                touch($path);
210
            }
211
        };
212
        $unlinkOperation = function (string $path) {
213
            unlink($path);
214
        };
215
        $unlinkAfter = function (string $path) {
216
            FileHelper::removeDirectory(dirname($path));
217
        };
218
219
        yield 'unlink matched' => [
220
            $path = __DIR__ . DIRECTORY_SEPARATOR . 'stub' . DIRECTORY_SEPARATOR . 'file-to-unlink.txt',
221
            $unlinkBefore,
222
            [],
223
            [],
224
            $unlinkOperation,
225
            $unlinkAfter,
226
            [
227
                'unlink' => [
228
                    ['path' => $path, 'args' => []],
229
                ],
230
            ],
231
        ];
232
        yield 'unlink ignored by path' => [
233
            $path,
234
            $unlinkBefore,
235
            ['/' . basename(__FILE__, '.php') . '/'],
236
            [],
237
            $unlinkOperation,
238
            $unlinkAfter,
239
            [],
240
        ];
241
        yield 'unlink ignored by class' => [
242
            $path,
243
            $unlinkBefore,
244
            [],
245
            [self::class],
246
            $unlinkOperation,
247
            $unlinkAfter,
248
            [],
249
        ];
250
251
        $fileStreamBefore = function (string $path) {
252
            if (!is_dir(dirname($path))) {
253
                mkdir(dirname($path), 0777, true);
254
            }
255
            if (!is_file($path)) {
256
                touch($path);
257
            }
258
        };
259
        $fileStreamOperation = function (string $path) {
260
            $stream = fopen($path, 'a+');
261
            fwrite($stream, 'test');
262
            fread($stream, 4);
263
            fseek($stream, 0);
264
            ftell($stream);
265
            feof($stream);
266
            ftruncate($stream, 0);
267
            fstat($stream);
268
            flock($stream, LOCK_EX);
269
            fclose($stream);
270
        };
271
        $fileStreamAfter = function (string $path) {
272
            FileHelper::removeDirectory(dirname($path));
273
        };
274
275
        yield 'file stream matched' => [
276
            $path = __DIR__ . DIRECTORY_SEPARATOR . 'stub' . DIRECTORY_SEPARATOR . 'file-to-stream.txt',
277
            $fileStreamBefore,
278
            [],
279
            [],
280
            $fileStreamOperation,
281
            $fileStreamAfter,
282
            [
283
                'write' => [
284
                    ['path' => $path, 'args' => []],
285
                ],
286
                'read' => [
287
                    ['path' => $path, 'args' => []],
288
                ],
289
            ],
290
        ];
291
        yield 'file stream ignored by path' => [
292
            $path,
293
            $fileStreamBefore,
294
            ['/' . basename(__FILE__, '.php') . '/'],
295
            [],
296
            $fileStreamOperation,
297
            $fileStreamAfter,
298
            [],
299
        ];
300
        yield 'file stream ignored by class' => [
301
            $path,
302
            $fileStreamBefore,
303
            [],
304
            [self::class],
305
            $fileStreamOperation,
306
            $fileStreamAfter,
307
            [],
308
        ];
309
    }
310
311
    protected function getCollector(): CollectorInterface
312
    {
313
        return new FilesystemStreamCollector();
314
    }
315
316
    protected function checkCollectedData(array $data): void
317
    {
318
        parent::checkCollectedData($data);
319
        $collected = $data;
320
        $this->assertCount(2, $collected);
321
322
        $this->assertCount(2, $collected['read']);
323
        $this->assertEquals([
324
            ['path' => __FILE__, 'args' => ['arg1' => 'v1', 'arg2' => 'v2']],
325
            ['path' => __FILE__, 'args' => ['arg3' => 'v3', 'arg4' => 'v4']],
326
        ], $collected['read']);
327
328
        $this->assertCount(1, $collected['mkdir']);
329
        $this->assertEquals([
330
            ['path' => __DIR__, 'args' => ['recursive']],
331
        ], $collected['mkdir']);
332
    }
333
334
    protected function checkSummaryData(array $data): void
335
    {
336
        parent::checkSummaryData($data);
337
        $this->assertArrayHasKey('fs_stream', $data);
338
        $this->assertEquals(
339
            ['read' => 2, 'mkdir' => 1],
340
            $data['fs_stream'],
341
            print_r($data, true),
0 ignored issues
show
Bug introduced by
It seems like print_r($data, true) can also be of type true; however, parameter $message of PHPUnit\Framework\Assert::assertEquals() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

341
            /** @scrutinizer ignore-type */ print_r($data, true),
Loading history...
342
        );
343
    }
344
}
345