Completed
Push — master ( fb964a...b7229e )
by Jonathan
9s
created

testGetValue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 0
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Doctrine\Tests\Common\Reflection;
4
5
use Doctrine\Common\Proxy\Proxy;
6
use Doctrine\Common\Reflection\RuntimePublicReflectionProperty;
7
use PHPUnit\Framework\TestCase;
8
use function call_user_func;
9
10
class RuntimePublicReflectionPropertyTest extends TestCase
11
{
12
    public function testGetValue() : void
13
    {
14
        $object = new RuntimePublicReflectionPropertyTestClass();
15
16
        $reflProperty = new RuntimePublicReflectionProperty(RuntimePublicReflectionPropertyTestClass::class, 'test');
17
18
        self::assertSame('testValue', $reflProperty->getValue($object));
19
20
        unset($object->test);
21
22
        self::assertNull($reflProperty->getValue($object));
23
    }
24
25
    public function testSetValue() : void
26
    {
27
        $object = new RuntimePublicReflectionPropertyTestClass();
28
29
        $reflProperty = new RuntimePublicReflectionProperty(RuntimePublicReflectionPropertyTestClass::class, 'test');
30
31
        self::assertSame('testValue', $reflProperty->getValue($object));
32
33
        $reflProperty->setValue($object, 'changedValue');
34
35
        self::assertSame('changedValue', $reflProperty->getValue($object));
36
    }
37
38
    public function testGetValueOnProxyPublicProperty() : void
39
    {
40
        $getCheckMock = $this->getMockBuilder('stdClass')->setMethods(['callGet'])->getMock();
41
        $getCheckMock->expects($this->never())->method('callGet');
42
        $initializer = function () use ($getCheckMock) {
43
            call_user_func($getCheckMock);
0 ignored issues
show
Bug introduced by
$getCheckMock of type PHPUnit\Framework\MockObject\MockObject is incompatible with the type callable expected by parameter $function of call_user_func(). ( Ignorable by Annotation )

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

43
            call_user_func(/** @scrutinizer ignore-type */ $getCheckMock);
Loading history...
44
        };
45
46
        $mockProxy = new RuntimePublicReflectionPropertyTestProxyMock();
47
        $mockProxy->__setInitializer($initializer);
48
49
        $reflProperty = new RuntimePublicReflectionProperty(
50
            __NAMESPACE__ . '\RuntimePublicReflectionPropertyTestProxyMock',
51
            'checkedProperty'
52
        );
53
54
        self::assertSame('testValue', $reflProperty->getValue($mockProxy));
55
        unset($mockProxy->checkedProperty);
56
        self::assertNull($reflProperty->getValue($mockProxy));
57
    }
58
59
    public function testSetValueOnProxyPublicProperty() : void
60
    {
61
        $setCheckMock = $this->getMockBuilder('stdClass')->setMethods(['neverCallSet'])->getMock();
62
        $setCheckMock->expects($this->never())->method('neverCallSet');
63
        $initializer = function () use ($setCheckMock) {
64
            call_user_func([$setCheckMock, 'neverCallSet']);
65
        };
66
67
        $mockProxy = new RuntimePublicReflectionPropertyTestProxyMock();
68
        $mockProxy->__setInitializer($initializer);
69
70
        $reflProperty = new RuntimePublicReflectionProperty(
71
            __NAMESPACE__ . '\RuntimePublicReflectionPropertyTestProxyMock',
72
            'checkedProperty'
73
        );
74
75
        $reflProperty->setValue($mockProxy, 'newValue');
76
        self::assertSame('newValue', $mockProxy->checkedProperty);
77
78
        unset($mockProxy->checkedProperty);
79
        $reflProperty->setValue($mockProxy, 'otherNewValue');
80
        self::assertSame('otherNewValue', $mockProxy->checkedProperty);
81
82
        $setCheckMock = $this->getMockBuilder('stdClass')->setMethods(['callSet'])->getMock();
83
        $setCheckMock->expects($this->once())->method('callSet');
84
        $initializer = function () use ($setCheckMock) {
85
            call_user_func([$setCheckMock, 'callSet']);
86
        };
87
88
        $mockProxy->__setInitializer($initializer);
89
        $mockProxy->__setInitialized(true);
90
91
        unset($mockProxy->checkedProperty);
92
        $reflProperty->setValue($mockProxy, 'againNewValue');
93
        self::assertSame('againNewValue', $mockProxy->checkedProperty);
94
    }
95
}
96
97
/**
98
 * Mock that simulates proxy public property lazy loading
99
 */
100
class RuntimePublicReflectionPropertyTestProxyMock implements Proxy
101
{
102
    /** @var \Closure|null */
103
    private $initializer = null;
104
105
    /** @var bool */
106
    private $initialized = false;
107
108
    /** @var string */
109
    public $checkedProperty = 'testValue';
110
111
    /**
112
     * {@inheritDoc}
113
     */
114
    public function __getInitializer()
115
    {
116
        return $this->initializer;
117
    }
118
119
    /**
120
     * {@inheritDoc}
121
     */
122
    public function __setInitializer(?\Closure $initializer = null)
123
    {
124
        $this->initializer = $initializer;
125
    }
126
127
    /**
128
     * {@inheritDoc}
129
     */
130
    public function __getLazyProperties()
131
    {
132
    }
133
134
    /**
135
     * {@inheritDoc}
136
     */
137
    public function __load()
138
    {
139
    }
140
141
    /**
142
     * {@inheritDoc}
143
     */
144
    public function __isInitialized()
145
    {
146
        return $this->initialized;
147
    }
148
149
    /**
150
     * {@inheritDoc}
151
     */
152
    public function __setInitialized($initialized)
153
    {
154
        $this->initialized = (bool) $initialized;
155
    }
156
157
    /**
158
     * @param string $name
159
     */
160
    public function __get($name)
161
    {
162
        if ($this->initializer) {
163
            $cb = $this->initializer;
164
            $cb();
165
        }
166
167
        return $this->checkedProperty;
168
    }
169
170
    /**
171
     * @param string $name
172
     * @param mixed  $value
173
     */
174
    public function __set($name, $value)
175
    {
176
        if ($this->initializer) {
177
            $cb = $this->initializer;
178
            $cb();
179
        }
180
181
        // triggers notices if `$name` is used: see https://bugs.php.net/bug.php?id=63463
182
        $this->checkedProperty = $value;
183
    }
184
185
    /**
186
     * @param string $name
187
     *
188
     * @return bool
189
     */
190
    public function __isset($name)
191
    {
192
        if ($this->initializer) {
193
            $cb = $this->initializer;
194
            $cb();
195
        }
196
197
        return isset($this->checkedProperty);
198
    }
199
200
    /**
201
     * {@inheritDoc}
202
     */
203
    public function __setCloner(?\Closure $cloner = null)
204
    {
205
    }
206
207
    /**
208
     * {@inheritDoc}
209
     */
210
    public function __getCloner()
211
    {
212
    }
213
}
214
215
class RuntimePublicReflectionPropertyTestClass
216
{
217
    /** @var string|null */
218
    public $test = 'testValue';
219
}
220