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

DumperTest::jsonDataProvider()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 249
Code Lines 160

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 160
nc 1
nop 0
dl 0
loc 249
rs 8
c 0
b 0
f 0

How to fix   Long Method   

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;
6
7
use PHPUnit\Framework\TestCase;
8
use stdClass;
9
use Yiisoft\Yii\Debug as D;
10
use Yiisoft\Yii\Debug\Dumper;
11
12
final class DumperTest extends TestCase
13
{
14
    /**
15
     * @dataProvider asJsonObjectMapDataProvider
16
     *
17
     * @param string $expectedResult
18
     *
19
     * @group JOM
20
     */
21
    public function testAsJsonObjectsMap(mixed $var, $expectedResult): void
22
    {
23
        $exportResult = Dumper::create($var)->asJsonObjectsMap();
24
        $this->assertEquals($expectedResult, $exportResult);
25
    }
26
27
    public function asJsonObjectMapDataProvider(): array
28
    {
29
        $user = new stdClass();
30
        $user->id = 1;
31
        $objectId = spl_object_id($user);
32
33
        $decoratedUser = clone $user;
34
        $decoratedUser->name = 'Name';
35
        $decoratedUser->originalUser = $user;
36
        $decoratedObjectId = spl_object_id($decoratedUser);
37
38
        return [
39
            [
40
                $user,
41
                <<<S
42
                [{"stdClass#{$objectId}":{"public \$id":1}}]
43
                S,
44
            ],
45
            [
46
                $decoratedUser,
47
                <<<S
48
                [{"stdClass#{$decoratedObjectId}":{"public \$id":1,"public \$name":"Name","public \$originalUser":"object@stdClass#{$objectId}"}},{"stdClass#{$objectId}":{"public \$id":1}}]
49
                S,
50
            ],
51
        ];
52
    }
53
54
    /**
55
     * @dataProvider jsonDataProvider()
56
     */
57
    public function testAsJson($variable, string $result): void
58
    {
59
        $output = Dumper::create($variable)->asJson();
60
        $this->assertEqualsWithoutLE($result, $output);
61
    }
62
63
    public static function jsonDataProvider(): iterable
64
    {
65
        $emptyObject = new stdClass();
66
        $emptyObjectId = spl_object_id($emptyObject);
67
68
        yield 'empty object' => [
69
            $emptyObject,
70
            <<<S
71
                {"stdClass#{$emptyObjectId}":"{stateless object}"}
72
                S,
73
        ];
74
75
        // @formatter:off
76
        $shortFunctionObject = fn () => 1;
77
        // @formatter:on
78
        $shortFunctionObjectId = spl_object_id($shortFunctionObject);
0 ignored issues
show
Bug introduced by
$shortFunctionObject of type callable is incompatible with the type object expected by parameter $object of spl_object_id(). ( Ignorable by Annotation )

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

78
        $shortFunctionObjectId = spl_object_id(/** @scrutinizer ignore-type */ $shortFunctionObject);
Loading history...
79
80
        yield 'short function' => [
81
            $shortFunctionObject,
82
            <<<S
83
                {"Closure#{$shortFunctionObjectId}":"fn () => 1"}
84
                S,
85
        ];
86
87
        // @formatter:off
88
        $staticShortFunctionObject = static fn () => 1;
89
        // @formatter:on
90
        $staticShortFunctionObjectId = spl_object_id($staticShortFunctionObject);
0 ignored issues
show
Bug introduced by
$staticShortFunctionObject of type callable is incompatible with the type object expected by parameter $object of spl_object_id(). ( Ignorable by Annotation )

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

90
        $staticShortFunctionObjectId = spl_object_id(/** @scrutinizer ignore-type */ $staticShortFunctionObject);
Loading history...
91
92
        yield 'short static function' => [
93
            $staticShortFunctionObject,
94
            <<<S
95
                {"Closure#{$staticShortFunctionObjectId}":"static fn () => 1"}
96
                S,
97
        ];
98
99
        // @formatter:off
100
        $functionObject = function () {
101
            return 1;
102
        };
103
        // @formatter:on
104
        $functionObjectId = spl_object_id($functionObject);
0 ignored issues
show
Bug introduced by
$functionObject of type callable is incompatible with the type object expected by parameter $object of spl_object_id(). ( Ignorable by Annotation )

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

104
        $functionObjectId = spl_object_id(/** @scrutinizer ignore-type */ $functionObject);
Loading history...
105
106
        yield 'function' => [
107
            $functionObject,
108
            <<<S
109
                {"Closure#{$functionObjectId}":"function () {\\n            return 1;\\n        }"}
110
                S,
111
        ];
112
113
        // @formatter:off
114
        $staticFunctionObject = static function () {
115
            return 1;
116
        };
117
        // @formatter:on
118
        $staticFunctionObjectId = spl_object_id($staticFunctionObject);
0 ignored issues
show
Bug introduced by
$staticFunctionObject of type callable is incompatible with the type object expected by parameter $object of spl_object_id(). ( Ignorable by Annotation )

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

118
        $staticFunctionObjectId = spl_object_id(/** @scrutinizer ignore-type */ $staticFunctionObject);
Loading history...
119
120
        yield 'static function' => [
121
            $staticFunctionObject,
122
            <<<S
123
                {"Closure#{$staticFunctionObjectId}":"static function () {\\n            return 1;\\n        }"}
124
                S,
125
        ];
126
        yield 'string' => [
127
            'Hello, Yii!',
128
            '"Hello, Yii!"',
129
        ];
130
        yield 'empty string' => [
131
            '',
132
            '""',
133
        ];
134
        yield 'null' => [
135
            null,
136
            'null',
137
        ];
138
        yield 'integer' => [
139
            1,
140
            '1',
141
        ];
142
        yield 'integer with separator' => [
143
            1_23_456,
0 ignored issues
show
Bug introduced by
The constant Yiisoft\Yii\Debug\Tests\Unit\1_23_456 was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
144
            '123456',
145
        ];
146
        yield 'boolean' => [
147
            true,
148
            'true',
149
        ];
150
        yield 'fileResource' => [
151
            fopen('php://input', 'rb'),
152
            '{"timed_out":false,"blocked":true,"eof":false,"wrapper_type":"PHP","stream_type":"Input","mode":"rb","unread_bytes":0,"seekable":true,"uri":"php:\/\/input"}',
153
        ];
154
        yield 'empty array' => [
155
            [],
156
            '[]',
157
        ];
158
        yield 'array of 3 elements, automatic keys' => [
159
            [
160
                'one',
161
                'two',
162
                'three',
163
            ],
164
            '["one","two","three"]',
165
        ];
166
        yield 'array of 3 elements, custom keys' => [
167
            [
168
                2 => 'one',
169
                'two' => 'two',
170
                0 => 'three',
171
            ],
172
            '{"2":"one","two":"two","0":"three"}',
173
        ];
174
175
        // @formatter:off
176
        $closureInArrayObject = fn () => new \DateTimeZone('');
177
        // @formatter:on
178
        $closureInArrayObjectId = spl_object_id($closureInArrayObject);
0 ignored issues
show
Bug introduced by
$closureInArrayObject of type callable is incompatible with the type object expected by parameter $object of spl_object_id(). ( Ignorable by Annotation )

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

178
        $closureInArrayObjectId = spl_object_id(/** @scrutinizer ignore-type */ $closureInArrayObject);
Loading history...
179
180
        yield 'closure in array' => [
181
            // @formatter:off
182
            [$closureInArrayObject],
183
            // @formatter:on
184
            <<<S
185
                [{"Closure#{$closureInArrayObjectId}":"fn () => new \\\DateTimeZone('')"}]
186
                S,
187
        ];
188
189
        // @formatter:off
190
        $closureWithUsualClassNameObject = fn (Dumper $date) => new \DateTimeZone('');
0 ignored issues
show
Unused Code introduced by
The parameter $date is not used and could be removed. ( Ignorable by Annotation )

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

190
        $closureWithUsualClassNameObject = fn (/** @scrutinizer ignore-unused */ Dumper $date) => new \DateTimeZone('');

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
191
        // @formatter:on
192
        $closureWithUsualClassNameObjectId = spl_object_id($closureWithUsualClassNameObject);
0 ignored issues
show
Bug introduced by
$closureWithUsualClassNameObject of type callable is incompatible with the type object expected by parameter $object of spl_object_id(). ( Ignorable by Annotation )

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

192
        $closureWithUsualClassNameObjectId = spl_object_id(/** @scrutinizer ignore-type */ $closureWithUsualClassNameObject);
Loading history...
193
194
        yield 'original class name' => [
195
            $closureWithUsualClassNameObject,
196
            <<<S
197
                {"Closure#{$closureWithUsualClassNameObjectId}":"fn (\\\Yiisoft\\\Yii\\\Debug\\\Dumper \$date) => new \\\DateTimeZone('')"}
198
                S,
199
        ];
200
201
        // @formatter:off
202
        $closureWithAliasedClassNameObject = fn (Dumper $date) => new \DateTimeZone('');
0 ignored issues
show
Unused Code introduced by
The parameter $date is not used and could be removed. ( Ignorable by Annotation )

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

202
        $closureWithAliasedClassNameObject = fn (/** @scrutinizer ignore-unused */ Dumper $date) => new \DateTimeZone('');

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
203
        // @formatter:on
204
        $closureWithAliasedClassNameObjectId = spl_object_id($closureWithAliasedClassNameObject);
0 ignored issues
show
Bug introduced by
$closureWithAliasedClassNameObject of type callable is incompatible with the type object expected by parameter $object of spl_object_id(). ( Ignorable by Annotation )

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

204
        $closureWithAliasedClassNameObjectId = spl_object_id(/** @scrutinizer ignore-type */ $closureWithAliasedClassNameObject);
Loading history...
205
206
        yield 'class alias' => [
207
            $closureWithAliasedClassNameObject,
208
            <<<S
209
                {"Closure#{$closureWithAliasedClassNameObjectId}":"fn (\\\Yiisoft\\\Yii\\\Debug\\\Dumper \$date) => new \\\DateTimeZone('')"}
210
                S,
211
        ];
212
213
        // @formatter:off
214
        $closureWithAliasedNamespaceObject = fn (D\Dumper $date) => new \DateTimeZone('');
0 ignored issues
show
Unused Code introduced by
The parameter $date is not used and could be removed. ( Ignorable by Annotation )

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

214
        $closureWithAliasedNamespaceObject = fn (/** @scrutinizer ignore-unused */ D\Dumper $date) => new \DateTimeZone('');

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
215
        // @formatter:on
216
        $closureWithAliasedNamespaceObjectId = spl_object_id($closureWithAliasedNamespaceObject);
0 ignored issues
show
Bug introduced by
$closureWithAliasedNamespaceObject of type callable is incompatible with the type object expected by parameter $object of spl_object_id(). ( Ignorable by Annotation )

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

216
        $closureWithAliasedNamespaceObjectId = spl_object_id(/** @scrutinizer ignore-type */ $closureWithAliasedNamespaceObject);
Loading history...
217
218
        yield 'namespace alias' => [
219
            $closureWithAliasedNamespaceObject,
220
            <<<S
221
                {"Closure#{$closureWithAliasedNamespaceObjectId}":"fn (\\\Yiisoft\\\Yii\\\Debug\\\Dumper \$date) => new \\\DateTimeZone('')"}
222
                S,
223
        ];
224
        // @formatter:off
225
        $closureWithNullCollisionOperatorObject = fn () => $_ENV['var'] ?? null;
226
        // @formatter:on
227
        $closureWithNullCollisionOperatorObjectId = spl_object_id($closureWithNullCollisionOperatorObject);
0 ignored issues
show
Bug introduced by
$closureWithNullCollisionOperatorObject of type callable is incompatible with the type object expected by parameter $object of spl_object_id(). ( Ignorable by Annotation )

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

227
        $closureWithNullCollisionOperatorObjectId = spl_object_id(/** @scrutinizer ignore-type */ $closureWithNullCollisionOperatorObject);
Loading history...
228
229
        yield 'closure with null-collision operator' => [
230
            $closureWithNullCollisionOperatorObject,
231
            <<<S
232
                {"Closure#{$closureWithNullCollisionOperatorObjectId}":"fn () => \$_ENV['var'] ?? null"}
233
                S,
234
        ];
235
        yield 'utf8 supported' => [
236
            '🤣',
237
            '"🤣"',
238
        ];
239
240
241
        $objectWithClosureInProperty = new stdClass();
242
        // @formatter:off
243
        $objectWithClosureInProperty->a = fn () => 1;
244
        // @formatter:on
245
        $objectWithClosureInPropertyId = spl_object_id($objectWithClosureInProperty);
246
        $objectWithClosureInPropertyClosureId = spl_object_id($objectWithClosureInProperty->a);
0 ignored issues
show
Bug introduced by
$objectWithClosureInProperty->a of type callable is incompatible with the type object expected by parameter $object of spl_object_id(). ( Ignorable by Annotation )

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

246
        $objectWithClosureInPropertyClosureId = spl_object_id(/** @scrutinizer ignore-type */ $objectWithClosureInProperty->a);
Loading history...
247
248
        yield 'closure in property supported' => [
249
            $objectWithClosureInProperty,
250
            <<<S
251
                {"stdClass#{$objectWithClosureInPropertyId}":{"public \$a":{"Closure#{$objectWithClosureInPropertyClosureId}":"fn () => 1"}}}
252
                S,
253
        ];
254
        yield 'binary string' => [
255
            pack('H*', md5('binary string')),
256
            '"ɍ��^��\u00191\u0017�]�-f�"',
257
        ];
258
259
260
        $fileResource = tmpfile();
261
        $fileResourceUri = stream_get_meta_data($fileResource)['uri'];
262
        $fileResourceUri = addcslashes($fileResourceUri, '/\\');
263
264
        yield 'file resource' => [
265
            $fileResource,
266
            <<<S
267
                {"timed_out":false,"blocked":true,"eof":false,"wrapper_type":"plainfile","stream_type":"STDIO","mode":"r+b","unread_bytes":0,"seekable":true,"uri":"{$fileResourceUri}"}
268
                S,
269
        ];
270
271
        $closedFileResource = tmpfile();
272
        fclose($closedFileResource);
273
274
        yield 'closed file resource' => [
275
            $closedFileResource,
276
            '"{closed resource}"',
277
        ];
278
279
        $opendirResource = opendir(sys_get_temp_dir());
280
281
        yield 'opendir resource' => [
282
            $opendirResource,
283
            <<<S
284
                {"timed_out":false,"blocked":true,"eof":false,"wrapper_type":"plainfile","stream_type":"dir","mode":"r","unread_bytes":0,"seekable":true}
285
                S,
286
        ];
287
288
        $curlResource = curl_init('https://example.com');
289
        $curlResourceObjectId = spl_object_id($curlResource);
0 ignored issues
show
Bug introduced by
It seems like $curlResource can also be of type resource; however, parameter $object of spl_object_id() does only seem to accept object, 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

289
        $curlResourceObjectId = spl_object_id(/** @scrutinizer ignore-type */ $curlResource);
Loading history...
290
291
        yield 'curl resource' => [
292
            $curlResource,
293
            <<<S
294
                {"CurlHandle#{$curlResourceObjectId}":"{stateless object}"}
295
                S,
296
        ];
297
        yield 'stdout' => [
298
            STDOUT,
299
            <<<S
300
                {"timed_out":false,"blocked":true,"eof":false,"wrapper_type":"PHP","stream_type":"STDIO","mode":"wb","unread_bytes":0,"seekable":false,"uri":"php:\/\/stdout"}
301
                S,
302
        ];
303
        yield 'stderr' => [
304
            STDERR,
305
            <<<S
306
                {"timed_out":false,"blocked":true,"eof":false,"wrapper_type":"PHP","stream_type":"STDIO","mode":"wb","unread_bytes":0,"seekable":false,"uri":"php:\/\/stderr"}
307
                S,
308
        ];
309
        yield 'stdin' => [
310
            STDIN,
311
            <<<S
312
                {"timed_out":false,"blocked":true,"eof":false,"wrapper_type":"PHP","stream_type":"STDIO","mode":"rb","unread_bytes":0,"seekable":false,"uri":"php:\/\/stdin"}
313
                S,
314
        ];
315
    }
316
317
    /**
318
     * Asserting two strings equality ignoring line endings.
319
     */
320
    protected function assertEqualsWithoutLE(string $expected, string $actual, string $message = ''): void
321
    {
322
        $expected = str_replace(["\r\n", '\r\n'], ["\n", '\n'], $expected);
323
        $actual = str_replace(["\r\n", '\r\n'], ["\n", '\n'], $actual);
324
        $this->assertEquals($expected, $actual, $message);
325
    }
326
}
327