Passed
Pull Request — 1.x (#3)
by Kevin
01:27
created

Object5::__toString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 1
c 1
b 0
f 1
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
namespace Zenstruck\Callback\Tests;
4
5
use PHPUnit\Framework\TestCase;
0 ignored issues
show
Bug introduced by
The type PHPUnit\Framework\TestCase 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...
6
use Zenstruck\Callback;
7
use Zenstruck\Callback\Argument;
8
use Zenstruck\Callback\Exception\UnresolveableArgument;
9
use Zenstruck\Callback\Parameter;
10
11
/**
12
 * @author Kevin Bond <[email protected]>
13
 */
14
final class CallbackTest extends TestCase
15
{
16
    /**
17
     * @test
18
     */
19
    public function create_must_be_callable(): void
20
    {
21
        $this->expectException(\InvalidArgumentException::class);
22
23
        Callback::createFor('not a callable');
24
    }
25
26
    /**
27
     * @test
28
     */
29
    public function invoke_all_can_enforce_min_arguments(): void
30
    {
31
        $callback = Callback::createFor(function() { return 'ret'; });
32
33
        $this->expectException(\ArgumentCountError::class);
34
35
        $callback->invokeAll(Parameter::untyped('foo'), 1);
36
    }
37
38
    /**
39
     * @test
40
     */
41
    public function invoke_all_with_no_arguments(): void
42
    {
43
        $actual = Callback::createFor(function() { return 'ret'; })
44
            ->invokeAll(Parameter::untyped('foo'))
45
        ;
46
47
        $this->assertSame('ret', $actual);
48
    }
49
50
    /**
51
     * @test
52
     */
53
    public function invoke_all_with_string_callable(): void
54
    {
55
        $actual = Callback::createFor('strtoupper')
56
            ->invokeAll(Parameter::union(
57
                Parameter::untyped('foobar'),
58
                Parameter::typed('string', 'foobar')
59
            )
60
        )
61
        ;
62
63
        $this->assertSame('FOOBAR', $actual);
64
    }
65
66
    /**
67
     * @test
68
     */
69
    public function invoke_all_untyped_argument(): void
70
    {
71
        $actual = Callback::createFor(function($string) { return \mb_strtoupper($string); })
72
            ->invokeAll(Parameter::untyped('foobar'))
73
        ;
74
75
        $this->assertSame('FOOBAR', $actual);
76
    }
77
78
    /**
79
     * @test
80
     */
81
    public function invoke_all_primitive_typed_argument(): void
82
    {
83
        $actual = Callback::createFor(function(string $string) { return \mb_strtoupper($string); })
84
            ->invokeAll(Parameter::typed('string', 'foobar'))
85
        ;
86
87
        $this->assertSame('FOOBAR', $actual);
88
    }
89
90
    /**
91
     * @test
92
     */
93
    public function invoke_all_class_arguments(): void
94
    {
95
        $object = new Object2();
96
        $function = static function(Object1 $object1, Object2 $object2, $object3) {
97
            return [
98
                'object1' => $object1,
99
                'object2' => $object2,
100
                'object3' => $object3,
101
            ];
102
        };
103
104
        $actual = Callback::createFor($function)
105
            ->invokeAll(Parameter::union(
106
                Parameter::untyped($object),
107
                Parameter::typed(Object1::class, $object)
108
            ))
109
        ;
110
111
        $this->assertSame(
112
            [
113
                'object1' => $object,
114
                'object2' => $object,
115
                'object3' => $object,
116
            ],
117
            $actual
118
        );
119
    }
120
121
    /**
122
     * @test
123
     */
124
    public function invoke_all_class_arguments_value_factories(): void
125
    {
126
        $function = static function(Object1 $object1, Object2 $object2, $object3) {
127
            return [
128
                'object1' => $object1,
129
                'object2' => $object2,
130
                'object3' => $object3,
131
            ];
132
        };
133
        $factoryArgs = [];
134
        $factory = Parameter::factory(static function($arg) use (&$factoryArgs) {
135
            $factoryArgs[] = $arg;
136
137
            if ($arg) {
138
                return new $arg();
139
            }
140
141
            return new Object1();
142
        });
143
144
        $ret = Callback::createFor($function)
145
            ->invokeAll(Parameter::union(
146
                Parameter::untyped($factory),
147
                Parameter::typed(Object1::class, $factory)
148
            ))
149
        ;
150
151
        $this->assertSame(['object1', 'object2', 'object3'], \array_keys($ret));
152
        $this->assertInstanceOf(Object1::class, $ret['object1']);
153
        $this->assertInstanceOf(Object2::class, $ret['object2']);
154
        $this->assertInstanceOf(Object1::class, $ret['object3']);
155
        $this->assertSame(
156
            [Object1::class, Object2::class, null],
157
            $factoryArgs
158
        );
159
    }
160
161
    /**
162
     * @test
163
     */
164
    public function invoke_all_unresolvable_parameter(): void
165
    {
166
        $callback = Callback::createFor(static function(Object1 $object1, Object2 $object2, Object3 $object3) {});
0 ignored issues
show
Unused Code introduced by
The parameter $object1 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

166
        $callback = Callback::createFor(static function(/** @scrutinizer ignore-unused */ Object1 $object1, Object2 $object2, Object3 $object3) {});

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...
Unused Code introduced by
The parameter $object2 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

166
        $callback = Callback::createFor(static function(Object1 $object1, /** @scrutinizer ignore-unused */ Object2 $object2, Object3 $object3) {});

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...
Unused Code introduced by
The parameter $object3 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

166
        $callback = Callback::createFor(static function(Object1 $object1, Object2 $object2, /** @scrutinizer ignore-unused */ Object3 $object3) {});

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...
167
168
        $this->expectException(UnresolveableArgument::class);
169
        $this->expectExceptionMessage('Unable to resolve argument 2 for callback. Expected type: "mixed|Zenstruck\Callback\Tests\Object1"');
170
171
        $callback->invokeAll(Parameter::union(
172
            Parameter::untyped(new Object1()),
173
            Parameter::typed(Object1::class, new Object1())
174
        ));
175
    }
176
177
    /**
178
     * @test
179
     */
180
    public function invoke_with_no_args(): void
181
    {
182
        $actual = Callback::createFor(function() { return 'ret'; })
183
            ->invoke()
184
        ;
185
186
        $this->assertSame('ret', $actual);
187
    }
188
189
    /**
190
     * @test
191
     */
192
    public function invoke_with_resolvable_args(): void
193
    {
194
        $object = new Object2();
195
        $function = static function(Object1 $object1, Object2 $object2, $object3, $extra) {
196
            return [
197
                'object1' => $object1,
198
                'object2' => $object2,
199
                'object3' => $object3,
200
                'extra' => $extra,
201
            ];
202
        };
203
204
        $actual = Callback::createFor($function)
205
            ->invoke(
206
                Parameter::typed(Object1::class, $object),
207
                Parameter::typed(Object2::class, $object),
208
                Parameter::untyped($object),
209
                'value'
210
            )
211
        ;
212
213
        $this->assertSame(
214
            [
215
                'object1' => $object,
216
                'object2' => $object,
217
                'object3' => $object,
218
                'extra' => 'value',
219
            ],
220
            $actual
221
        );
222
    }
223
224
    /**
225
     * @test
226
     */
227
    public function invoke_with_unresolvable_argument(): void
228
    {
229
        $object = new Object2();
230
        $function = static function(Object1 $object1, $object2, $object3, $extra) {};
0 ignored issues
show
Unused Code introduced by
The parameter $object3 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

230
        $function = static function(Object1 $object1, $object2, /** @scrutinizer ignore-unused */ $object3, $extra) {};

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...
Unused Code introduced by
The parameter $object1 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

230
        $function = static function(/** @scrutinizer ignore-unused */ Object1 $object1, $object2, $object3, $extra) {};

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...
Unused Code introduced by
The parameter $extra 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

230
        $function = static function(Object1 $object1, $object2, $object3, /** @scrutinizer ignore-unused */ $extra) {};

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...
Unused Code introduced by
The parameter $object2 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

230
        $function = static function(Object1 $object1, /** @scrutinizer ignore-unused */ $object2, $object3, $extra) {};

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...
231
232
        $this->expectException(UnresolveableArgument::class);
233
        $this->expectExceptionMessage('Unable to resolve argument 2 for callback. Expected type: "Zenstruck\Callback\Tests\Object2"');
234
235
        Callback::createFor($function)
236
            ->invoke(
237
                Parameter::typed(Object1::class, $object),
238
                Parameter::typed(Object2::class, $object),
239
                Parameter::untyped($object),
240
                'value'
241
            )
242
        ;
243
    }
244
245
    /**
246
     * @test
247
     */
248
    public function invoke_with_not_enough_required_arguments(): void
249
    {
250
        $object = new Object2();
251
        $function = static function(Object1 $object1) {};
0 ignored issues
show
Unused Code introduced by
The parameter $object1 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

251
        $function = static function(/** @scrutinizer ignore-unused */ Object1 $object1) {};

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...
252
253
        $this->expectException(\ArgumentCountError::class);
254
        $this->expectExceptionMessage('No argument 2 for callable. Expected type: "Zenstruck\Callback\Tests\Object2"');
255
256
        Callback::createFor($function)
257
            ->invoke(
258
                Parameter::typed(Object1::class, $object),
259
                Parameter::typed(Object2::class, $object),
260
                Parameter::untyped($object),
261
                'value'
262
            )
263
        ;
264
    }
265
266
    /**
267
     * @test
268
     */
269
    public function can_mark_invoke_parameter_arguments_as_optional(): void
270
    {
271
        $actual = Callback::createFor(static function() { return 'ret'; })
272
            ->invoke(Parameter::typed('string', 'foobar')->optional())
273
        ;
274
275
        $this->assertSame('ret', $actual);
276
277
        $actual = Callback::createFor(static function(string $v) { return $v; })
278
            ->invoke(Parameter::typed('string', 'foobar')->optional())
279
        ;
280
281
        $this->assertSame('foobar', $actual);
282
    }
283
284
    /**
285
     * @test
286
     */
287
    public function is_stringable(): void
288
    {
289
        $this->assertStringMatchesFormat(__CLASS__.':%d', (string) Callback::createFor(function() {}));
290
        $this->assertStringMatchesFormat(__CLASS__.':%d', (string) Callback::createFor([$this, __METHOD__]));
291
        $this->assertStringMatchesFormat(Object4::class.':%d', (string) Callback::createFor(new Object4()));
292
        $this->assertStringMatchesFormat(Object4::class.':%d', (string) Callback::createFor([Object4::class, 'staticMethod']));
293
        $this->assertSame(__NAMESPACE__.'\test_function', (string) Callback::createFor(__NAMESPACE__.'\test_function'));
294
    }
295
296
    /**
297
     * @test
298
     * @requires PHP >= 8.0
299
     */
300
    public function invoke_can_support_union_typehints(): void
301
    {
302
        // hack to allow test suite to run on php 7 w/o syntax errors
303
        eval('$callback = fn(\Zenstruck\Callback\Tests\Object1|string $arg) => \'ret\';');
0 ignored issues
show
introduced by
The use of eval() is discouraged.
Loading history...
304
305
        $this->assertSame('ret', Callback::createFor($callback)->invokeAll(Parameter::typed(Object1::class, new Object1())));
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $callback seems to be never defined.
Loading history...
306
        $this->assertSame('ret', Callback::createFor($callback)->invokeAll(Parameter::typed('string', 'value')));
307
        $this->assertSame('ret', Callback::createFor($callback)->invoke(Parameter::typed(Object1::class, new Object1())));
308
        $this->assertSame('ret', Callback::createFor($callback)->invoke(Parameter::typed('string', 'value')));
309
    }
310
311
    /**
312
     * @test
313
     */
314
    public function can_get_callback_arguments(): void
315
    {
316
        $callback = Callback::createFor(function(Object1 $a, $b, string $c) {});
0 ignored issues
show
Unused Code introduced by
The parameter $c 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

316
        $callback = Callback::createFor(function(Object1 $a, $b, /** @scrutinizer ignore-unused */ string $c) {});

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...
Unused Code introduced by
The parameter $a 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

316
        $callback = Callback::createFor(function(/** @scrutinizer ignore-unused */ Object1 $a, $b, string $c) {});

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...
Unused Code introduced by
The parameter $b 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

316
        $callback = Callback::createFor(function(Object1 $a, /** @scrutinizer ignore-unused */ $b, string $c) {});

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...
317
318
        $this->assertSame(Object1::class, $callback->argument(0)->type());
319
        $this->assertNull($callback->argument(1)->type());
320
        $this->assertSame('string', $callback->argument(2)->type());
321
        $this->assertSame(
322
            [
323
                Object1::class,
324
                null,
325
                'string',
326
            ],
327
            \array_map(function(Argument $a) { return $a->type(); }, $callback->arguments())
328
        );
329
    }
330
331
    /**
332
     * @test
333
     * @requires PHP >= 8.0
334
     */
335
    public function can_get_union_callback_arguments(): void
336
    {
337
        // hack to allow test suite to run on php 7 w/o syntax errors
338
        eval('$callback = fn(\Zenstruck\Callback\Tests\Object1|string $a, $b, string $c) => null;');
0 ignored issues
show
introduced by
The use of eval() is discouraged.
Loading history...
339
        $callback = Callback::createFor($callback);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $callback seems to be never defined.
Loading history...
340
341
        $this->assertSame(Object1::class.'|string', $callback->argument(0)->type());
342
        $this->assertNull($callback->argument(1)->type());
343
        $this->assertSame('string', $callback->argument(2)->type());
344
        $this->assertSame(
345
            [
346
                Object1::class.'|string',
347
                null,
348
                'string',
349
            ],
350
            \array_map(function(Argument $a) { return $a->type(); }, $callback->arguments())
351
        );
352
    }
353
354
    /**
355
     * @test
356
     */
357
    public function exception_thrown_when_trying_to_access_invalid_argument(): void
358
    {
359
        $this->expectException(\OutOfRangeException::class);
360
361
        Callback::createFor(function() {})->argument(0);
362
    }
363
364
    /**
365
     * @test
366
     */
367
    public function value_factory_injects_argument_if_type_hinted(): void
368
    {
369
        $callback = Callback::createFor(function(string $a, int $b, $c) { return [$a, $b, $c]; });
370
        $factory = Parameter::factory(function(Argument $argument) {
371
            if ($argument->supports('string')) {
372
                return 'string';
373
            }
374
375
            if ($argument->supports('int')) {
376
                return 17;
377
            }
378
379
            return 'invalid';
380
        });
381
382
        $ret = $callback->invokeAll(
383
            Parameter::union(
384
                Parameter::typed('string', $factory),
385
                Parameter::typed('int', $factory),
386
                Parameter::untyped($factory)
387
            )
388
        );
389
390
        $this->assertSame(['string', 17, 'string'], $ret);
391
    }
392
393
    /**
394
     * @test
395
     */
396
    public function can_use_value_factory_with_no_argument(): void
397
    {
398
        $ret = Callback::createFor(function($value) { return $value; })
399
            ->invoke(Parameter::untyped(Parameter::factory(function() { return 'value'; })))
400
        ;
401
402
        $this->assertSame('value', $ret);
403
    }
404
405
    /**
406
     * @test
407
     * @requires PHP >= 8.0
408
     */
409
    public function value_factory_can_be_used_with_union_arguments_if_no_value_factory_argument(): void
410
    {
411
        // hack to allow test suite to run on php 7 w/o syntax errors
412
        eval('$callback = fn(\Zenstruck\Callback\Tests\Object1|string $a) => $a;');
0 ignored issues
show
introduced by
The use of eval() is discouraged.
Loading history...
413
414
        $ret = Callback::createFor($callback)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $callback seems to be never defined.
Loading history...
415
            ->invoke(Parameter::typed('string', Parameter::factory(function() { return 'value'; })))
416
        ;
417
418
        $this->assertSame('value', $ret);
419
    }
420
421
    /**
422
     * @test
423
     * @requires PHP >= 8.0
424
     */
425
    public function value_factory_can_be_used_with_union_arguments_as_array(): void
426
    {
427
        $array = [];
428
        $factory = Parameter::factory(function(array $types) use (&$array) {
429
            $array = $types;
430
431
            return 'value';
432
        });
433
434
        // hack to allow test suite to run on php 7 w/o syntax errors
435
        eval('$callback = fn(\Zenstruck\Callback\Tests\Object1|string $a) => $a;');
0 ignored issues
show
introduced by
The use of eval() is discouraged.
Loading history...
436
        $ret = Callback::createFor($callback)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $callback seems to be never defined.
Loading history...
437
            ->invoke(Parameter::typed('string', $factory))
438
        ;
439
440
        $this->assertSame('value', $ret);
441
        $this->assertSame([Object1::class, 'string'], $array);
442
    }
443
444
    /**
445
     * @test
446
     * @requires PHP >= 8.0
447
     */
448
    public function value_factory_cannot_accept_union_argument(): void
449
    {
450
        $this->expectException(\LogicException::class);
451
452
        // hack to allow test suite to run on php 7 w/o syntax errors
453
        eval('$callback = fn(\Zenstruck\Callback\Tests\Object1|string $a) => $a;');
0 ignored issues
show
introduced by
The use of eval() is discouraged.
Loading history...
454
455
        Callback::createFor($callback)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $callback seems to be never defined.
Loading history...
456
            ->invoke(Parameter::typed('string', Parameter::factory(function(string $type) { return $type; })))
457
        ;
458
    }
459
460
    /**
461
     * @test
462
     */
463
    public function argument_supports(): void
464
    {
465
        $callback1 = Callback::createFor(function(?Object1 $object, string $string, int $int, $noType) {});
0 ignored issues
show
Unused Code introduced by
The parameter $noType 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

465
        $callback1 = Callback::createFor(function(?Object1 $object, string $string, int $int, /** @scrutinizer ignore-unused */ $noType) {});

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...
Unused Code introduced by
The parameter $int 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

465
        $callback1 = Callback::createFor(function(?Object1 $object, string $string, /** @scrutinizer ignore-unused */ int $int, $noType) {});

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...
Unused Code introduced by
The parameter $string 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

465
        $callback1 = Callback::createFor(function(?Object1 $object, /** @scrutinizer ignore-unused */ string $string, int $int, $noType) {});

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...
Unused Code introduced by
The parameter $object 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

465
        $callback1 = Callback::createFor(function(/** @scrutinizer ignore-unused */ ?Object1 $object, string $string, int $int, $noType) {});

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...
466
        $callback2 = Callback::createFor(function(Object2 $object, string $string, $noType) {});
0 ignored issues
show
Unused Code introduced by
The parameter $noType 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

466
        $callback2 = Callback::createFor(function(Object2 $object, string $string, /** @scrutinizer ignore-unused */ $noType) {});

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...
Unused Code introduced by
The parameter $string 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

466
        $callback2 = Callback::createFor(function(Object2 $object, /** @scrutinizer ignore-unused */ string $string, $noType) {});

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...
Unused Code introduced by
The parameter $object 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

466
        $callback2 = Callback::createFor(function(/** @scrutinizer ignore-unused */ Object2 $object, string $string, $noType) {});

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...
467
468
        $this->assertTrue($callback1->argument(0)->supports(Object1::class));
469
        $this->assertTrue($callback1->argument(0)->supports(Object2::class));
470
        $this->assertTrue($callback1->argument(0)->supports('null'));
471
        $this->assertTrue($callback1->argument(0)->supports('NULL'));
472
        $this->assertFalse($callback1->argument(0)->supports('string'));
473
        $this->assertFalse($callback1->argument(0)->supports(Object3::class));
474
        $this->assertFalse($callback1->argument(0)->supports(Object2::class, Argument::EXACT));
475
476
        $this->assertTrue($callback1->argument(1)->supports('string'));
477
        $this->assertFalse($callback1->argument(1)->supports('int'));
478
479
        $this->assertTrue($callback1->argument(2)->supports('int'));
480
        $this->assertTrue($callback1->argument(2)->supports('integer'));
481
482
        $this->assertTrue($callback1->argument(3)->supports(Object1::class));
483
        $this->assertTrue($callback1->argument(3)->supports(Object2::class));
484
        $this->assertTrue($callback1->argument(3)->supports('string'));
485
        $this->assertTrue($callback1->argument(3)->supports('int'));
486
487
        $this->assertTrue($callback2->argument(0)->supports(Object1::class, Argument::EXACT|Argument::COVARIANCE|Argument::CONTRAVARIANCE));
488
        $this->assertFalse($callback2->argument(0)->supports(Object3::class, Argument::EXACT|Argument::COVARIANCE|Argument::CONTRAVARIANCE));
489
    }
490
491
    /**
492
     * @test
493
     */
494
    public function argument_allows(): void
495
    {
496
        $callback1 = Callback::createFor(function(Object1 $object, string $string, int $int, $noType) {});
0 ignored issues
show
Unused Code introduced by
The parameter $object 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

496
        $callback1 = Callback::createFor(function(/** @scrutinizer ignore-unused */ Object1 $object, string $string, int $int, $noType) {});

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...
Unused Code introduced by
The parameter $noType 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

496
        $callback1 = Callback::createFor(function(Object1 $object, string $string, int $int, /** @scrutinizer ignore-unused */ $noType) {});

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...
Unused Code introduced by
The parameter $string 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

496
        $callback1 = Callback::createFor(function(Object1 $object, /** @scrutinizer ignore-unused */ string $string, int $int, $noType) {});

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...
Unused Code introduced by
The parameter $int 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

496
        $callback1 = Callback::createFor(function(Object1 $object, string $string, /** @scrutinizer ignore-unused */ int $int, $noType) {});

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...
497
        $callback2 = Callback::createFor(function(Object2 $object, string $string, $noType) {});
0 ignored issues
show
Unused Code introduced by
The parameter $string 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

497
        $callback2 = Callback::createFor(function(Object2 $object, /** @scrutinizer ignore-unused */ string $string, $noType) {});

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...
Unused Code introduced by
The parameter $noType 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

497
        $callback2 = Callback::createFor(function(Object2 $object, string $string, /** @scrutinizer ignore-unused */ $noType) {});

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...
Unused Code introduced by
The parameter $object 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

497
        $callback2 = Callback::createFor(function(/** @scrutinizer ignore-unused */ Object2 $object, string $string, $noType) {});

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...
498
499
        $this->assertTrue($callback1->argument(0)->allows(new Object1()));
500
        $this->assertTrue($callback1->argument(0)->allows(new Object2()));
501
        $this->assertFalse($callback1->argument(0)->allows('string'));
502
        $this->assertFalse($callback1->argument(0)->allows(new Object3()));
503
504
        $this->assertTrue($callback1->argument(1)->allows('string'));
505
        $this->assertFalse($callback1->argument(1)->allows(16));
506
507
        $this->assertTrue($callback1->argument(2)->allows(16));
508
        $this->assertFalse($callback1->argument(2)->allows('string'));
509
        $this->assertFalse($callback1->argument(2)->allows(16.0));
510
511
        $this->assertTrue($callback1->argument(3)->allows(new Object1()));
512
        $this->assertTrue($callback1->argument(3)->allows(new Object2()));
513
        $this->assertTrue($callback1->argument(3)->allows('string'));
514
        $this->assertTrue($callback1->argument(3)->allows(16));
515
516
        $this->assertFalse($callback2->argument(0)->allows(new Object1()));
517
        $this->assertFalse($callback2->argument(0)->allows(new Object3()));
518
    }
519
}
520
521
class Object1
522
{
523
}
524
525
class Object2 extends Object1
526
{
527
}
528
529
class Object3
530
{
531
}
532
533
class Object4
534
{
535
    public function __invoke()
536
    {
537
    }
538
539
    public static function staticMethod()
540
    {
541
    }
542
}
543
544
class Object5
545
{
546
    public function __toString(): string
547
    {
548
        return 'value';
549
    }
550
}
551
552
function test_function()
553
{
554
}
555