Completed
Pull Request — master (#266)
by Marco
15:13
created

testPropertyExistence()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 8
rs 9.4286
cc 1
eloc 5
nc 1
nop 3
1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license.
17
 */
18
19
namespace ProxyManagerTest\Functional;
20
21
use PHPUnit_Framework_TestCase;
22
use ProxyManager\Factory\AccessInterceptorValueHolderFactory;
23
use ProxyManager\Generator\ClassGenerator;
24
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
25
use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy;
26
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolderGenerator;
27
use ProxyManagerTestAsset\BaseClass;
28
use ProxyManagerTestAsset\BaseInterface;
29
use ProxyManagerTestAsset\ClassWithCounterConstructor;
30
use ProxyManagerTestAsset\ClassWithMethodWithByRefVariadicFunction;
31
use ProxyManagerTestAsset\ClassWithMethodWithVariadicFunction;
32
use ProxyManagerTestAsset\ClassWithPublicArrayProperty;
33
use ProxyManagerTestAsset\ClassWithPublicProperties;
34
use ProxyManagerTestAsset\ClassWithSelfHint;
35
use ReflectionClass;
36
use stdClass;
37
38
/**
39
 * Tests for {@see \ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerator} produced objects
40
 *
41
 * @author Marco Pivetta <[email protected]>
42
 * @license MIT
43
 *
44
 * @group Functional
45
 * @coversNothing
46
 */
47
class AccessInterceptorValueHolderFunctionalTest extends PHPUnit_Framework_TestCase
48
{
49
    /**
50
     * @dataProvider getProxyMethods
51
     *
52
     * @param string  $className
53
     * @param object  $instance
54
     * @param string  $method
55
     * @param mixed[] $params
56
     * @param mixed   $expectedValue
57
     */
58
    public function testMethodCalls($className, $instance, $method, $params, $expectedValue)
59
    {
60
        $proxyName = $this->generateProxy($className);
61
62
        /* @var $proxy \ProxyManager\Proxy\AccessInterceptorInterface|\ProxyManager\Proxy\ValueHolderInterface */
63
        $proxy     = $proxyName::staticProxyConstructor($instance);
64
65
        $this->assertSame($instance, $proxy->getWrappedValueHolderValue());
66
        $this->assertSame($expectedValue, call_user_func_array([$proxy, $method], $params));
67
68
        /* @var $listener callable|\PHPUnit_Framework_MockObject_MockObject */
69
        $listener = $this->getMock(stdClass::class, ['__invoke']);
70
        $listener
71
            ->expects($this->once())
72
            ->method('__invoke')
73
            ->with($proxy, $instance, $method, $params, false);
74
75
        $proxy->setMethodPrefixInterceptor(
0 ignored issues
show
Bug introduced by
The method setMethodPrefixInterceptor does only exist in ProxyManager\Proxy\AccessInterceptorInterface, but not in ProxyManager\Proxy\ValueHolderInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
76
            $method,
77
            function ($proxy, $instance, $method, $params, & $returnEarly) use ($listener) {
78
                $listener($proxy, $instance, $method, $params, $returnEarly);
79
            }
80
        );
81
82
        $this->assertSame($expectedValue, call_user_func_array([$proxy, $method], $params));
83
84
        $random = uniqid();
85
86
        $proxy->setMethodPrefixInterceptor(
0 ignored issues
show
Bug introduced by
The method setMethodPrefixInterceptor does only exist in ProxyManager\Proxy\AccessInterceptorInterface, but not in ProxyManager\Proxy\ValueHolderInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
87
            $method,
88
            function ($proxy, $instance, $method, $params, & $returnEarly) use ($random) {
89
                $returnEarly = true;
90
91
                return $random;
92
            }
93
        );
94
95
        $this->assertSame($random, call_user_func_array([$proxy, $method], $params));
96
    }
97
98
    /**
99
     * @dataProvider getProxyMethods
100
     *
101
     * @param string  $className
102
     * @param object  $instance
103
     * @param string  $method
104
     * @param mixed[] $params
105
     * @param mixed   $expectedValue
106
     */
107
    public function testMethodCallsWithSuffixListener($className, $instance, $method, $params, $expectedValue)
108
    {
109
        $proxyName = $this->generateProxy($className);
110
111
        /* @var $proxy \ProxyManager\Proxy\AccessInterceptorInterface|\ProxyManager\Proxy\ValueHolderInterface */
112
        $proxy    = $proxyName::staticProxyConstructor($instance);
113
        /* @var $listener callable|\PHPUnit_Framework_MockObject_MockObject */
114
        $listener = $this->getMock(stdClass::class, ['__invoke']);
115
        $listener
116
            ->expects($this->once())
117
            ->method('__invoke')
118
            ->with($proxy, $instance, $method, $params, $expectedValue, false);
119
120
        $proxy->setMethodSuffixInterceptor(
0 ignored issues
show
Bug introduced by
The method setMethodSuffixInterceptor does only exist in ProxyManager\Proxy\AccessInterceptorInterface, but not in ProxyManager\Proxy\ValueHolderInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
121
            $method,
122
            function ($proxy, $instance, $method, $params, $returnValue, & $returnEarly) use ($listener) {
123
                $listener($proxy, $instance, $method, $params, $returnValue, $returnEarly);
124
            }
125
        );
126
127
        $this->assertSame($expectedValue, call_user_func_array([$proxy, $method], $params));
128
129
        $random = uniqid();
130
131
        $proxy->setMethodSuffixInterceptor(
0 ignored issues
show
Bug introduced by
The method setMethodSuffixInterceptor does only exist in ProxyManager\Proxy\AccessInterceptorInterface, but not in ProxyManager\Proxy\ValueHolderInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
132
            $method,
133
            function ($proxy, $instance, $method, $params, $returnValue, & $returnEarly) use ($random) {
134
                $returnEarly = true;
135
136
                return $random;
137
            }
138
        );
139
140
        $this->assertSame($random, call_user_func_array([$proxy, $method], $params));
141
    }
142
143
    /**
144
     * @dataProvider getProxyMethods
145
     *
146
     * @param string  $className
147
     * @param object  $instance
148
     * @param string  $method
149
     * @param mixed[] $params
150
     * @param mixed   $expectedValue
151
     */
152
    public function testMethodCallsAfterUnSerialization($className, $instance, $method, $params, $expectedValue)
153
    {
154
        $proxyName = $this->generateProxy($className);
155
        /* @var $proxy \ProxyManager\Proxy\AccessInterceptorInterface|\ProxyManager\Proxy\ValueHolderInterface */
156
        $proxy     = unserialize(serialize($proxyName::staticProxyConstructor($instance)));
157
158
        $this->assertSame($expectedValue, call_user_func_array([$proxy, $method], $params));
159
        $this->assertEquals($instance, $proxy->getWrappedValueHolderValue());
0 ignored issues
show
Bug introduced by
The method getWrappedValueHolderValue does only exist in ProxyManager\Proxy\ValueHolderInterface, but not in ProxyManager\Proxy\AccessInterceptorInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
160
    }
161
162
    /**
163
     * @dataProvider getProxyMethods
164
     *
165
     * @param string  $className
166
     * @param object  $instance
167
     * @param string  $method
168
     * @param mixed[] $params
169
     * @param mixed   $expectedValue
170
     */
171
    public function testMethodCallsAfterCloning($className, $instance, $method, $params, $expectedValue)
172
    {
173
        $proxyName = $this->generateProxy($className);
174
175
        /* @var $proxy \ProxyManager\Proxy\AccessInterceptorInterface|\ProxyManager\Proxy\ValueHolderInterface */
176
        $proxy     = $proxyName::staticProxyConstructor($instance);
177
        $cloned    = clone $proxy;
178
179
        $this->assertNotSame($proxy->getWrappedValueHolderValue(), $cloned->getWrappedValueHolderValue());
180
        $this->assertSame($expectedValue, call_user_func_array([$cloned, $method], $params));
181
        $this->assertEquals($instance, $cloned->getWrappedValueHolderValue());
182
    }
183
184
    /**
185
     * @dataProvider getPropertyAccessProxies
186
     *
187
     * @param object                                                                                  $instance
188
     * @param \ProxyManager\Proxy\AccessInterceptorInterface|\ProxyManager\Proxy\ValueHolderInterface $proxy
189
     * @param string                                                                                  $publicProperty
190
     * @param mixed                                                                                   $propertyValue
191
     */
192
    public function testPropertyReadAccess($instance, $proxy, $publicProperty, $propertyValue)
193
    {
194
        $this->assertSame($propertyValue, $proxy->$publicProperty);
195
        $this->assertEquals($instance, $proxy->getWrappedValueHolderValue());
0 ignored issues
show
Bug introduced by
The method getWrappedValueHolderValue does only exist in ProxyManager\Proxy\ValueHolderInterface, but not in ProxyManager\Proxy\AccessInterceptorInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
196
    }
197
198
    /**
199
     * @dataProvider getPropertyAccessProxies
200
     *
201
     * @param object                                                                                  $instance
202
     * @param \ProxyManager\Proxy\AccessInterceptorInterface|\ProxyManager\Proxy\ValueHolderInterface $proxy
203
     * @param string                                                                                  $publicProperty
204
     */
205
    public function testPropertyWriteAccess($instance, $proxy, $publicProperty)
206
    {
207
        $newValue               = uniqid();
208
        $proxy->$publicProperty = $newValue;
209
210
        $this->assertSame($newValue, $proxy->$publicProperty);
211
        $this->assertSame($newValue, $proxy->getWrappedValueHolderValue()->$publicProperty);
212
    }
213
214
    /**
215
     * @dataProvider getPropertyAccessProxies
216
     *
217
     * @param object                                                                                  $instance
218
     * @param \ProxyManager\Proxy\AccessInterceptorInterface|\ProxyManager\Proxy\ValueHolderInterface $proxy
219
     * @param string                                                                                  $publicProperty
220
     */
221
    public function testPropertyExistence($instance, $proxy, $publicProperty)
222
    {
223
        $this->assertSame(isset($instance->$publicProperty), isset($proxy->$publicProperty));
224
        $this->assertEquals($instance, $proxy->getWrappedValueHolderValue());
0 ignored issues
show
Bug introduced by
The method getWrappedValueHolderValue does only exist in ProxyManager\Proxy\ValueHolderInterface, but not in ProxyManager\Proxy\AccessInterceptorInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
225
226
        $proxy->getWrappedValueHolderValue()->$publicProperty = null;
227
        $this->assertFalse(isset($proxy->$publicProperty));
228
    }
229
230
    /**
231
     * @dataProvider getPropertyAccessProxies
232
     *
233
     * @param object                                                                                  $instance
234
     * @param \ProxyManager\Proxy\AccessInterceptorInterface|\ProxyManager\Proxy\ValueHolderInterface $proxy
235
     * @param string                                                                                  $publicProperty
236
     */
237
    public function testPropertyUnset($instance, $proxy, $publicProperty)
238
    {
239
        $instance = $proxy->getWrappedValueHolderValue() ? $proxy->getWrappedValueHolderValue() : $instance;
240
        unset($proxy->$publicProperty);
241
242
        $this->assertFalse(isset($instance->$publicProperty));
243
        $this->assertFalse(isset($proxy->$publicProperty));
244
    }
245
246
    /**
247
     * Verifies that accessing a public property containing an array behaves like in a normal context
248
     */
249
    public function testCanWriteToArrayKeysInPublicProperty()
250
    {
251
        $instance    = new ClassWithPublicArrayProperty();
252
        $className   = get_class($instance);
253
        $proxyName   = $this->generateProxy($className);
254
        /* @var $proxy ClassWithPublicArrayProperty */
255
        $proxy       = $proxyName::staticProxyConstructor($instance);
256
257
        $proxy->arrayProperty['foo'] = 'bar';
258
259
        $this->assertSame('bar', $proxy->arrayProperty['foo']);
260
261
        $proxy->arrayProperty = ['tab' => 'taz'];
262
263
        $this->assertSame(['tab' => 'taz'], $proxy->arrayProperty);
264
    }
265
266
    /**
267
     * Verifies that public properties retrieved via `__get` don't get modified in the object state
268
     */
269
    public function testWillNotModifyRetrievedPublicProperties()
270
    {
271
        $instance    = new ClassWithPublicProperties();
272
        $className   = get_class($instance);
273
        $proxyName   = $this->generateProxy($className);
274
        /* @var $proxy ClassWithPublicProperties */
275
        $proxy       = $proxyName::staticProxyConstructor($instance);
276
        $variable    = $proxy->property0;
277
278
        $this->assertSame('property0', $variable);
279
280
        $variable = 'foo';
281
282
        $this->assertSame('property0', $proxy->property0);
283
        $this->assertSame('foo', $variable);
284
    }
285
286
    /**
287
     * Verifies that public properties references retrieved via `__get` modify in the object state
288
     */
289
    public function testWillModifyByRefRetrievedPublicProperties()
290
    {
291
        $instance    = new ClassWithPublicProperties();
292
        $className   = get_class($instance);
293
        $proxyName   = $this->generateProxy($className);
294
        /* @var $proxy ClassWithPublicProperties */
295
        $proxy       = $proxyName::staticProxyConstructor($instance);
296
        $variable    = & $proxy->property0;
297
298
        $this->assertSame('property0', $variable);
299
300
        $variable = 'foo';
301
302
        $this->assertSame('foo', $proxy->property0);
303
        $this->assertSame('foo', $variable);
304
    }
305
306
    /**
307
     * @group 115
308
     * @group 175
309
     */
310
    public function testWillBehaveLikeObjectWithNormalConstructor()
311
    {
312
        $instance = new ClassWithCounterConstructor(10);
313
314
        $this->assertSame(10, $instance->amount, 'Verifying that test asset works as expected');
315
        $this->assertSame(10, $instance->getAmount(), 'Verifying that test asset works as expected');
316
        $instance->__construct(3);
317
        $this->assertSame(13, $instance->amount, 'Verifying that test asset works as expected');
318
        $this->assertSame(13, $instance->getAmount(), 'Verifying that test asset works as expected');
319
320
        $proxyName = $this->generateProxy(get_class($instance));
321
322
        /* @var $proxy ClassWithCounterConstructor */
323
        $proxy = new $proxyName(15);
324
325
        $this->assertSame(15, $proxy->amount, 'Verifying that the proxy constructor works as expected');
326
        $this->assertSame(15, $proxy->getAmount(), 'Verifying that the proxy constructor works as expected');
327
        $proxy->__construct(5);
328
        $this->assertSame(20, $proxy->amount, 'Verifying that the proxy constructor works as expected');
329
        $this->assertSame(20, $proxy->getAmount(), 'Verifying that the proxy constructor works as expected');
330
    }
331
332
    public function testCanCreateAndRegisterCallbackWithVariadicNotation()
333
    {
334
        $factory       = new AccessInterceptorValueHolderFactory();
335
        $targetObject  = new ClassWithMethodWithVariadicFunction();
336
337
        /* @var $object ClassWithMethodWithVariadicFunction */
338
        $object = $factory->createProxy(
339
            $targetObject,
340
            [
341
                function ($paratemers) {
342
                    return 'Foo Baz';
343
                },
344
            ]
345
        );
346
347
        $this->assertNull($object->bar);
348
        $this->assertNull($object->baz);
349
350
        $object->foo('Ocramius', 'Malukenho', 'Danizord');
351
        $this->assertSame('Ocramius', $object->bar);
352
        $this->assertSame(['Malukenho', 'Danizord'], $object->baz);
353
    }
354
355
    public function testCanCreateAndRegisterCallbackWithByRefVariadicNotation()
356
    {
357
        $factory       = new AccessInterceptorValueHolderFactory();
358
        $targetObject  = new ClassWithMethodWithByRefVariadicFunction();
359
360
        /* @var $object ClassWithMethodWithByRefVariadicFunction */
361
        $object = $factory->createProxy(
362
            $targetObject,
363
            [
364
                function ($paratemers) {
365
                    return 'Foo Baz';
366
                },
367
            ]
368
        );
369
370
        $arguments = ['Ocramius', 'Malukenho', 'Danizord'];
371
372
        self::assertSame(
373
            ['Ocramius', 'changed', 'Danizord'],
374
            (new ClassWithMethodWithByRefVariadicFunction())->tuz(...$arguments),
375
            'Verifying that the implementation of the test asset is correct before proceeding'
376
        );
377
        self::assertSame(['Ocramius', 'changed', 'Danizord'], $object->tuz(...$arguments));
378
        self::assertSame(['Ocramius', 'changed', 'Danizord'], $arguments, 'By-ref arguments were changed');
379
    }
380
381
    /**
382
     * Generates a proxy for the given class name, and retrieves its class name
383
     *
384
     * @param string $parentClassName
385
     *
386
     * @return string
387
     */
388
    private function generateProxy($parentClassName)
389
    {
390
        $generatedClassName = __NAMESPACE__ . '\\' . UniqueIdentifierGenerator::getIdentifier('Foo');
391
        $generator          = new AccessInterceptorValueHolderGenerator();
392
        $generatedClass     = new ClassGenerator($generatedClassName);
393
        $strategy           = new EvaluatingGeneratorStrategy();
394
395
        $generator->generate(new ReflectionClass($parentClassName), $generatedClass);
396
        $strategy->generate($generatedClass);
397
398
        return $generatedClassName;
399
    }
400
401
    /**
402
     * Generates a list of object | invoked method | parameters | expected result
403
     *
404
     * @return array
405
     */
406
    public function getProxyMethods()
407
    {
408
        $selfHintParam = new ClassWithSelfHint();
409
410
        return [
411
            [
412
                BaseClass::class,
413
                new BaseClass(),
414
                'publicMethod',
415
                [],
416
                'publicMethodDefault'
417
            ],
418
            [
419
                BaseClass::class,
420
                new BaseClass(),
421
                'publicTypeHintedMethod',
422
                ['param' => new stdClass()],
423
                'publicTypeHintedMethodDefault'
424
            ],
425
            [
426
                BaseClass::class,
427
                new BaseClass(),
428
                'publicByReferenceMethod',
429
                [],
430
                'publicByReferenceMethodDefault'
431
            ],
432
            [
433
                BaseInterface::class,
434
                new BaseClass(),
435
                'publicMethod',
436
                [],
437
                'publicMethodDefault'
438
            ],
439
            [
440
                ClassWithSelfHint::class,
441
                new ClassWithSelfHint(),
442
                'selfHintMethod',
443
                ['parameter' => $selfHintParam],
444
                $selfHintParam
445
            ],
446
        ];
447
    }
448
449
    /**
450
     * Generates proxies and instances with a public property to feed to the property accessor methods
451
     *
452
     * @return array
453
     */
454
    public function getPropertyAccessProxies()
455
    {
456
        $instance1  = new BaseClass();
457
        $proxyName1 = $this->generateProxy(get_class($instance1));
458
        $instance2  = new BaseClass();
459
        $proxyName2 = $this->generateProxy(get_class($instance2));
460
461
        return [
462
            [
463
                $instance1,
464
                $proxyName1::staticProxyConstructor($instance1),
465
                'publicProperty',
466
                'publicPropertyDefault',
467
            ],
468
            [
469
                $instance2,
470
                unserialize(serialize($proxyName2::staticProxyConstructor($instance2))),
471
                'publicProperty',
472
                'publicPropertyDefault',
473
            ],
474
        ];
475
    }
476
}
477