NullObjectFunctionalTest   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 189
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 3
dl 0
loc 189
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A testMethodCalls() 0 6 1
A testMethodCallsAfterUnSerialization() 0 7 1
A testMethodCallsAfterCloning() 0 6 1
A testPropertyReadAccess() 0 4 1
A testPropertyWriteAccess() 0 7 1
A testPropertyExistence() 0 4 1
A testPropertyUnset() 0 6 1
B getProxyMethods() 0 62 1
A getPropertyAccessProxies() 0 19 1
A assertNullMethodCall() 0 10 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ProxyManagerTest\Functional;
6
7
use PHPUnit\Framework\TestCase;
8
use ProxyManager\Factory\NullObjectFactory;
9
use ProxyManager\Proxy\NullObjectInterface;
10
use ProxyManagerTestAsset\BaseClass;
11
use ProxyManagerTestAsset\BaseInterface;
12
use ProxyManagerTestAsset\ClassWithMethodWithByRefVariadicFunction;
13
use ProxyManagerTestAsset\ClassWithMethodWithVariadicFunction;
14
use ProxyManagerTestAsset\ClassWithParentHint;
15
use ProxyManagerTestAsset\ClassWithSelfHint;
16
use ProxyManagerTestAsset\EmptyClass;
17
use ProxyManagerTestAsset\VoidCounter;
18
use stdClass;
19
use function array_values;
20
use function random_int;
21
use function serialize;
22
use function uniqid;
23
use function unserialize;
24
25
/**
26
 * Tests for {@see \ProxyManager\ProxyGenerator\NullObjectGenerator} produced objects
27
 *
28
 * @group Functional
29
 * @coversNothing
30
 */
31
final class NullObjectFunctionalTest extends TestCase
32
{
33
    /**
34
     * @param mixed[] $params
35
     *
36
     * @dataProvider getProxyMethods
37
     *
38
     * @psalm-param class-string $className
39
     */
40
    public function testMethodCalls(string $className, string $method, array $params) : void
41
    {
42
        $proxy = (new NullObjectFactory())->createProxy($className);
43
44
        $this->assertNullMethodCall($proxy, $method, $params);
45
    }
46
47
    /**
48
     * @param mixed[] $params
49
     *
50
     * @dataProvider getProxyMethods
51
     *
52
     * @psalm-param class-string $className
53
     */
54
    public function testMethodCallsAfterUnSerialization(string $className, string $method, array $params) : void
55
    {
56
        /** @var NullObjectInterface $proxy */
57
        $proxy = unserialize(serialize((new NullObjectFactory())->createProxy($className)));
58
59
        $this->assertNullMethodCall($proxy, $method, $params);
60
    }
61
62
    /**
63
     * @param mixed[] $params
64
     *
65
     * @dataProvider getProxyMethods
66
     *
67
     * @psalm-param class-string $className
68
     */
69
    public function testMethodCallsAfterCloning(string $className, string $method, array $params) : void
70
    {
71
        $proxy = (new NullObjectFactory())->createProxy($className);
72
73
        $this->assertNullMethodCall(clone $proxy, $method, $params);
74
    }
75
76
    /**
77
     * @dataProvider getPropertyAccessProxies
78
     */
79
    public function testPropertyReadAccess(NullObjectInterface $proxy, string $publicProperty) : void
80
    {
81
        self::assertNull($proxy->$publicProperty);
0 ignored issues
show
Bug introduced by
The method assertNull() does not exist on ProxyManagerTest\Functio...ullObjectFunctionalTest. Did you maybe mean assertNullMethodCall()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
82
    }
83
84
    /**
85
     * @dataProvider getPropertyAccessProxies
86
     */
87
    public function testPropertyWriteAccess(NullObjectInterface $proxy, string $publicProperty) : void
88
    {
89
        $newValue               = uniqid('', true);
90
        $proxy->$publicProperty = $newValue;
91
92
        self::assertSame($newValue, $proxy->$publicProperty);
0 ignored issues
show
Bug introduced by
The method assertSame() does not seem to exist on object<ProxyManagerTest\...llObjectFunctionalTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
93
    }
94
95
    /**
96
     * @dataProvider getPropertyAccessProxies
97
     */
98
    public function testPropertyExistence(NullObjectInterface $proxy, string $publicProperty) : void
99
    {
100
        self::assertNull($proxy->$publicProperty);
0 ignored issues
show
Bug introduced by
The method assertNull() does not exist on ProxyManagerTest\Functio...ullObjectFunctionalTest. Did you maybe mean assertNullMethodCall()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
101
    }
102
103
    /**
104
     * @dataProvider getPropertyAccessProxies
105
     */
106
    public function testPropertyUnset(NullObjectInterface $proxy, string $publicProperty) : void
107
    {
108
        unset($proxy->$publicProperty);
109
110
        self::assertFalse(isset($proxy->$publicProperty));
0 ignored issues
show
Bug introduced by
The method assertFalse() does not seem to exist on object<ProxyManagerTest\...llObjectFunctionalTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
111
    }
112
113
    /**
114
     * Generates a list of object | invoked method | parameters | expected result
115
     *
116
     * @return string[][]|null[][]|mixed[][][]|object[][]
117
     */
118
    public function getProxyMethods() : array
119
    {
120
        $selfHintParam = new ClassWithSelfHint();
121
        $empty         = new EmptyClass();
122
123
        return [
124
            [
125
                BaseClass::class,
126
                'publicMethod',
127
                [],
128
                'publicMethodDefault',
129
            ],
130
            [
131
                BaseClass::class,
132
                'publicTypeHintedMethod',
133
                ['param' => new stdClass()],
134
                'publicTypeHintedMethodDefault',
135
            ],
136
            [
137
                BaseClass::class,
138
                'publicByReferenceMethod',
139
                [],
140
                'publicByReferenceMethodDefault',
141
            ],
142
            [
143
                BaseInterface::class,
144
                'publicMethod',
145
                [],
146
                'publicMethodDefault',
147
            ],
148
            [
149
                ClassWithSelfHint::class,
150
                'selfHintMethod',
151
                ['parameter' => $selfHintParam],
152
                $selfHintParam,
153
            ],
154
            [
155
                ClassWithParentHint::class,
156
                'parentHintMethod',
157
                ['parameter' => $empty],
158
                $empty,
159
            ],
160
            [
161
                ClassWithMethodWithVariadicFunction::class,
162
                'buz',
163
                ['Ocramius', 'Malukenho'],
164
                null,
165
            ],
166
            [
167
                ClassWithMethodWithByRefVariadicFunction::class,
168
                'tuz',
169
                ['Ocramius', 'Malukenho'],
170
                null,
171
            ],
172
            [
173
                VoidCounter::class,
174
                'increment',
175
                [random_int(10, 1000)],
176
                null,
177
            ],
178
        ];
179
    }
180
181
    /**
182
     * Generates proxies and instances with a public property to feed to the property accessor methods
183
     *
184
     * @return array<int, array<int, NullObjectInterface|string>>
0 ignored issues
show
Documentation introduced by
The doc-type array<int, could not be parsed: Expected ">" at position 5, but found "end of type". (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
185
     */
186
    public function getPropertyAccessProxies() : array
187
    {
188
        $factory = new NullObjectFactory();
189
        /** @var NullObjectInterface $serialized */
190
        $serialized = unserialize(serialize($factory->createProxy(BaseClass::class)));
191
192
        return [
193
            [
194
                $factory->createProxy(BaseClass::class),
195
                'publicProperty',
196
                'publicPropertyDefault',
197
            ],
198
            [
199
                $serialized,
200
                'publicProperty',
201
                'publicPropertyDefault',
202
            ],
203
        ];
204
    }
205
206
    /**
207
     * @param mixed[] $parameters
208
     */
209
    private function assertNullMethodCall(NullObjectInterface $proxy, string $methodName, array $parameters) : void
210
    {
211
        $method = [$proxy, $methodName];
212
213
        self::assertIsCallable($method);
0 ignored issues
show
Bug introduced by
The method assertIsCallable() does not seem to exist on object<ProxyManagerTest\...llObjectFunctionalTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
214
215
        $parameterValues = array_values($parameters);
216
217
        self::assertNull($method(...$parameterValues));
0 ignored issues
show
Bug introduced by
The method assertNull() does not exist on ProxyManagerTest\Functio...ullObjectFunctionalTest. Did you maybe mean assertNullMethodCall()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
218
    }
219
}
220