-
Notifications
You must be signed in to change notification settings - Fork 87
/
ReflectionClosure6Test.php
117 lines (88 loc) · 3.06 KB
/
ReflectionClosure6Test.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<?php declare(strict_types=1);
namespace Opis\Closure\Test;
use Closure;
use Opis\Closure\ReflectionClosure;
// Fake
use Opis\Closure\SerializableClosure;
use Some\ClassName as ClassAlias;
final class ReflectionClosure6Test extends \PHPUnit\Framework\TestCase
{
protected function c(Closure $closure)
{
$r = new ReflectionClosure($closure);
return $r->getCode();
}
protected function s($closure)
{
$closure = new SerializableClosure($closure);
return unserialize(serialize($closure))->getClosure();
}
public function testUnionTypes()
{
$f1 = fn(): string|int|false|Bar|null => 1;
$e1 = 'fn(): string|int|false|\Opis\Closure\Test\Bar|null => 1';
$f2 = fn(): \Foo|\Bar => 1;
$e2 = 'fn(): \Foo|\Bar => 1';
$f3 = fn(): int|false => false;
$e3 = 'fn(): int|false => false';
$f4 = function (): null|MyClass|ClassAlias|Relative\Ns\ClassName|\Absolute\Ns\ClassName { return null; };
$e4 = 'function (): null|\Opis\Closure\Test\MyClass|\Some\ClassName|\Opis\Closure\Test\Relative\Ns\ClassName|\Absolute\Ns\ClassName { return null; }';
$this->assertEquals($e1, $this->c($f1));
$this->assertEquals($e2, $this->c($f2));
$this->assertEquals($e3, $this->c($f3));
$this->assertEquals($e4, $this->c($f4));
self::assertTrue(true);
}
public function testMixedType()
{
$f1 = function (): mixed { return 42; };
$e1 = 'function (): mixed { return 42; }';
$this->assertEquals($e1, $this->c($f1));
}
public function testNullsafeOperator()
{
$f1 = function () { $obj = new \stdClass(); return $obj?->invalid(); };
$e1 = 'function () { $obj = new \stdClass(); return $obj?->invalid(); }';
$this->assertEquals($e1, $this->c($f1));
}
public function testTraillingComma()
{
$f1 = function (string $param,) {};
$e1 = 'function (string $param,) {}';
$this->assertEquals($e1, $this->c($f1));
}
public function testNamedParameter()
{
$f1 = function(string $firstName, string $lastName) { return $firstName . ' ' . $lastName;};
$unserialized = $this->s($f1);
$this->assertEquals('Marco Deleu', $unserialized(
lastName: 'Deleu',
firstName: 'Marco'
));
}
public function testConstructorPropertyPromotion()
{
$class = new PropertyPromotion('public', 'protected', 'private');
$f1 = fn() => $class;
$object = $this->s($f1)();
$this->assertEquals('public', $object->public);
$this->assertEquals('protected', $object->getProtected());
$this->assertEquals('private', $object->getPrivate());
}
}
class PropertyPromotion
{
public function __construct(
public string $public,
protected string $protected,
private string $private,
) {}
public function getProtected(): string
{
return $this->protected;
}
public function getPrivate(): string
{
return $this->private;
}
}