dataSkipCollectOnMatchIgnoreReferences()   C
last analyzed

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 PHPUnit\Framework\Attributes\DataProvider;
8
use Yiisoft\Files\FileHelper;
9
use Yiisoft\Yii\Debug\Collector\CollectorInterface;
10
use Yiisoft\Yii\Debug\Collector\Stream\FilesystemStreamCollector;
11
use Yiisoft\Yii\Debug\Tests\Shared\AbstractCollectorTestCase;
12
13
final class FilesystemStreamCollectorTest extends AbstractCollectorTestCase
14
{
15
    /**
16
     * @param FilesystemStreamCollector $collector
17
     */
18
    protected function collectTestData(CollectorInterface $collector): void
19
    {
20
        $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

20
        $collector->/** @scrutinizer ignore-call */ 
21
                    collect(
Loading history...
21
            operation: 'read',
22
            path: __FILE__,
23
            args: ['arg1' => 'v1', 'arg2' => 'v2'],
24
        );
25
        $collector->collect(
26
            operation: 'read',
27
            path: __FILE__,
28
            args: ['arg3' => 'v3', 'arg4' => 'v4'],
29
        );
30
        $collector->collect(
31
            operation: 'mkdir',
32
            path: __DIR__,
33
            args: ['recursive'],
34
        );
35
    }
36
37
    #[DataProvider('dataSkipCollectOnMatchIgnoreReferences')]
38
    public function testSkipCollectOnMatchIgnoreReferences(
39
        string $path,
40
        callable $before,
41
        array $ignoredPathPatterns,
42
        array $ignoredClasses,
43
        callable $operation,
44
        callable $after,
45
        array $result,
46
    ): void {
47
        $before($path);
48
49
        try {
50
            $collector = new FilesystemStreamCollector(
51
                ignoredPathPatterns: $ignoredPathPatterns,
52
                ignoredClasses: $ignoredClasses,
53
            );
54
            $collector->startup();
55
56
            $operation($path);
57
58
            $collected = $collector->getCollected();
59
            $collector->shutdown();
60
        } finally {
61
            $after($path);
62
        }
63
        $this->assertEquals($result, $collected);
64
    }
65
66
    public static function dataSkipCollectOnMatchIgnoreReferences(): iterable
67
    {
68
        $mkdirBefore = static function (string $path) {
69
            if (is_dir($path)) {
70
                @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

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

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