Completed
Pull Request — master (#266)
by Marco
06:25
created

testMethodCallsAfterUnSerialization()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 9
rs 9.6667
cc 1
eloc 5
nc 1
nop 5
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 testWillForwardVariadicArguments()
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
    /**
356
     * @group 265
357
     */
358
    public function testWillForwardVariadicByRefArguments()
359
    {
360
        $factory       = new AccessInterceptorValueHolderFactory();
361
        $targetObject  = new ClassWithMethodWithByRefVariadicFunction();
362
363
        /* @var $object ClassWithMethodWithByRefVariadicFunction */
364
        $object = $factory->createProxy(
365
            $targetObject,
366
            [
367
                function ($paratemers) {
0 ignored issues
show
Unused Code introduced by
The parameter $paratemers is not used and could be removed.

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

Loading history...
368
                    return 'Foo Baz';
369
                },
370
            ]
371
        );
372
373
        $arguments = ['Ocramius', 'Malukenho', 'Danizord'];
374
375
        self::assertSame(
376
            ['Ocramius', 'changed', 'Danizord'],
377
            (new ClassWithMethodWithByRefVariadicFunction())->tuz(...$arguments),
378
            'Verifying that the implementation of the test asset is correct before proceeding'
379
        );
380
        self::assertSame(['Ocramius', 'changed', 'Danizord'], $object->tuz(...$arguments));
381
        self::assertSame(['Ocramius', 'changed', 'Danizord'], $arguments, 'By-ref arguments were changed');
382
    }
383
384
    /**
385
     * Generates a proxy for the given class name, and retrieves its class name
386
     *
387
     * @param string $parentClassName
388
     *
389
     * @return string
390
     */
391
    private function generateProxy($parentClassName)
392
    {
393
        $generatedClassName = __NAMESPACE__ . '\\' . UniqueIdentifierGenerator::getIdentifier('Foo');
394
        $generator          = new AccessInterceptorValueHolderGenerator();
395
        $generatedClass     = new ClassGenerator($generatedClassName);
396
        $strategy           = new EvaluatingGeneratorStrategy();
397
398
        $generator->generate(new ReflectionClass($parentClassName), $generatedClass);
399
        $strategy->generate($generatedClass);
400
401
        return $generatedClassName;
402
    }
403
404
    /**
405
     * Generates a list of object | invoked method | parameters | expected result
406
     *
407
     * @return array
408
     */
409
    public function getProxyMethods()
410
    {
411
        $selfHintParam = new ClassWithSelfHint();
412
413
        return [
414
            [
415
                BaseClass::class,
416
                new BaseClass(),
417
                'publicMethod',
418
                [],
419
                'publicMethodDefault'
420
            ],
421
            [
422
                BaseClass::class,
423
                new BaseClass(),
424
                'publicTypeHintedMethod',
425
                ['param' => new stdClass()],
426
                'publicTypeHintedMethodDefault'
427
            ],
428
            [
429
                BaseClass::class,
430
                new BaseClass(),
431
                'publicByReferenceMethod',
432
                [],
433
                'publicByReferenceMethodDefault'
434
            ],
435
            [
436
                BaseInterface::class,
437
                new BaseClass(),
438
                'publicMethod',
439
                [],
440
                'publicMethodDefault'
441
            ],
442
            [
443
                ClassWithSelfHint::class,
444
                new ClassWithSelfHint(),
445
                'selfHintMethod',
446
                ['parameter' => $selfHintParam],
447
                $selfHintParam
448
            ],
449
        ];
450
    }
451
452
    /**
453
     * Generates proxies and instances with a public property to feed to the property accessor methods
454
     *
455
     * @return array
456
     */
457
    public function getPropertyAccessProxies()
458
    {
459
        $instance1  = new BaseClass();
460
        $proxyName1 = $this->generateProxy(get_class($instance1));
461
        $instance2  = new BaseClass();
462
        $proxyName2 = $this->generateProxy(get_class($instance2));
463
464
        return [
465
            [
466
                $instance1,
467
                $proxyName1::staticProxyConstructor($instance1),
468
                'publicProperty',
469
                'publicPropertyDefault',
470
            ],
471
            [
472
                $instance2,
473
                unserialize(serialize($proxyName2::staticProxyConstructor($instance2))),
474
                'publicProperty',
475
                'publicPropertyDefault',
476
            ],
477
        ];
478
    }
479
}
480