Issues (259)

Tests/Mapping/CallDefinitionTest.php (10 issues)

1
<?php
2
/**
3
 * Copyright (C) 2017  Gerrit Addiks.
4
 * This package (including this file) was released under the terms of the GPL-3.0.
5
 * You should have received a copy of the GNU General Public License along with this program.
6
 * If not, see <http://www.gnu.org/licenses/> or send me a mail so i can send you a copy.
7
 * @license GPL-3.0
8
 * @author Gerrit Addiks <[email protected]>
9
 */
10
11
namespace Addiks\RDMBundle\Tests\Mapping;
12
13
use PHPUnit\Framework\TestCase;
14
use Addiks\RDMBundle\Mapping\CallDefinition;
15
use Addiks\RDMBundle\Mapping\MappingInterface;
16
use Addiks\RDMBundle\Tests\Hydration\EntityExample;
17
use Addiks\RDMBundle\Hydration\HydrationContextInterface;
18
use Addiks\RDMBundle\Tests\ValueObjectExample;
19
use Symfony\Component\DependencyInjection\ContainerInterface;
20
use Addiks\RDMBundle\Tests\Hydration\ServiceExample;
21
22
final class CallDefinitionTest extends TestCase
23
{
24
25
    /**
26
     * @var CallDefinition
27
     */
28
    private $callDefinition;
29
30
    /**
31
     * @var ContainerInterface
32
     */
33
    private $container;
34
35
    /**
36
     * @var MappingInterface
37
     */
38
    private $argumentMappingA;
39
40
    /**
41
     * @var MappingInterface
42
     */
43
    private $argumentMappingB;
44
45
    private static $valueObjectToCreate;
46
47
    public function setUp(
48
        string $routineName = "someRoutineName",
49
        string $objectReference = "someObjectReference",
50
        bool $isStaticCall = true,
51
        bool $useArgumentMappingB = true
52
    ): void {
53
        $this->container = $this->createMock(ContainerInterface::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createMock(Symfon...tainerInterface::class) of type PHPUnit\Framework\MockObject\MockObject is incompatible with the declared type Symfony\Component\Depend...tion\ContainerInterface of property $container.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
54
        $this->argumentMappingA = $this->createMock(MappingInterface::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createMock(Addiks...appingInterface::class) of type PHPUnit\Framework\MockObject\MockObject is incompatible with the declared type Addiks\RDMBundle\Mapping\MappingInterface of property $argumentMappingA.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
55
        $this->argumentMappingB = $this->createMock(MappingInterface::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createMock(Addiks...appingInterface::class) of type PHPUnit\Framework\MockObject\MockObject is incompatible with the declared type Addiks\RDMBundle\Mapping\MappingInterface of property $argumentMappingB.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
56
57
        /** @var array<MappingInterface> $argumentMappings */
58
        $argumentMappings = [
59
            $this->argumentMappingA,
60
        ];
61
62
        if ($useArgumentMappingB) {
63
            $argumentMappings[] = $this->argumentMappingB;
64
        }
65
66
        $this->callDefinition = new CallDefinition(
67
            $this->container,
68
            $routineName,
69
            $objectReference,
70
            $argumentMappings,
71
            $isStaticCall
72
        );
73
    }
74
75
    /**
76
     * @test
77
     */
78
    public function shouldStoreObjectReference()
79
    {
80
        $this->assertEquals("someObjectReference", $this->callDefinition->getObjectReference());
81
    }
82
83
    /**
84
     * @test
85
     */
86
    public function shouldStoreRoutineName()
87
    {
88
        $this->assertEquals("someRoutineName", $this->callDefinition->getRoutineName());
89
    }
90
91
    /**
92
     * @test
93
     */
94
    public function shouldKnowIfStatic()
95
    {
96
        $this->assertEquals(true, $this->callDefinition->isStaticCall());
97
    }
98
99
    /**
100
     * @test
101
     */
102
    public function shouldStoreArgumentMapping()
103
    {
104
        $this->assertEquals([
105
            $this->createMock(MappingInterface::class),
106
            $this->createMock(MappingInterface::class),
107
        ], $this->callDefinition->getArgumentMappings());
108
    }
109
110
    /**
111
     * @test
112
     * @dataProvider dataProviderForShouldExecuteCallDefinitionOnEntity
113
     */
114
    public function shouldExecuteCallDefinitionOnEntity(
115
        string $objectReference,
116
        string $routineName,
117
        $argumentResult,
118
        $expectedResult,
119
        array $hydrationStack,
120
        $entity
121
    ) {
122
        $this->setUp($routineName, $objectReference, false, false);
123
124
        /** @var HydrationContextInterface $context */
125
        $context = $this->createMock(HydrationContextInterface::class);
126
        $context->method('getEntityClass')->willReturn(EntityExample::class);
0 ignored issues
show
The method method() does not exist on Addiks\RDMBundle\Hydrati...drationContextInterface. ( Ignorable by Annotation )

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

126
        $context->/** @scrutinizer ignore-call */ 
127
                  method('getEntityClass')->willReturn(EntityExample::class);

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...
127
        $context->method('getEntity')->willReturn($entity);
128
        $context->method('getObjectHydrationStack')->willReturn($hydrationStack);
129
130
        /** @var array<string> $dataFromAdditionalColumns */
131
        $dataFromAdditionalColumns = array(
132
            'lorem' => 'ipsum',
133
            'dolor' => 'sit amet'
134
        );
135
136
        $this->argumentMappingA->method('resolveValue')->will($this->returnCallback(
137
            function ($context, $dataFromAdditionalColumns) use ($argumentResult) {
0 ignored issues
show
The parameter $dataFromAdditionalColumns is not used and could be removed. ( Ignorable by Annotation )

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

137
            function ($context, /** @scrutinizer ignore-unused */ $dataFromAdditionalColumns) use ($argumentResult) {

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

Loading history...
The parameter $context is not used and could be removed. ( Ignorable by Annotation )

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

137
            function (/** @scrutinizer ignore-unused */ $context, $dataFromAdditionalColumns) use ($argumentResult) {

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

Loading history...
138
                return $argumentResult;
139
            }
140
        ));
141
142
        /** @var mixed $actualResult */
143
        $actualResult = $this->callDefinition->execute(
144
            $context,
145
            $dataFromAdditionalColumns
146
        );
147
148
        $this->assertSame($expectedResult, $actualResult);
149
    }
150
151
    public function dataProviderForShouldExecuteCallDefinitionOnEntity(): array
152
    {
153
        /** @var EntityExample $entity */
154
        $entity = $this->createMock(EntityExample::class);
155
156
        /** @var ValueObjectExample $expectedResult */
157
        $expectedResult = $this->createMock(ValueObjectExample::class);
158
159
        /** @var MappingInterface $mapping */
160
        $mapping = $this->createMock(MappingInterface::class);
161
162
        $entity->method('getBoo')->willReturn($expectedResult);
0 ignored issues
show
The method method() does not exist on Addiks\RDMBundle\Tests\Hydration\EntityExample. ( Ignorable by Annotation )

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

162
        $entity->/** @scrutinizer ignore-call */ 
163
                 method('getBoo')->willReturn($expectedResult);

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...
163
164
        return array(
165
            [
166
                '$this',
167
                'getBoo',
168
                null,
169
                $expectedResult,
170
                [
171
                    $entity,
172
                    $this->createMock(EntityExample::class),
173
                    $entity
174
                ],
175
                $entity
176
            ],
177
            [
178
                'self',
179
                'getBoo',
180
                null,
181
                $expectedResult,
182
                [
183
                    $entity,
184
                    $this->createMock(EntityExample::class),
185
                    $entity
186
                ],
187
                $entity
188
            ],
189
            [
190
                'parent',
191
                'getBoo',
192
                null,
193
                $expectedResult,
194
                [
195
                    $entity,
196
                    $entity,
197
                    $this->createMock(EntityExample::class)
198
                ],
199
                $entity
200
            ],
201
            [
202
                '',
203
                'spl_object_hash',
204
                $mapping,
205
                spl_object_hash($mapping),
206
                [
207
                    $entity,
208
                    $entity,
209
                    $this->createMock(EntityExample::class)
210
                ],
211
                $entity
212
            ],
213
        );
214
    }
215
216
    /**
217
     * @test
218
     */
219
    public function shouldExecuteCallDefinitionOnStaticEntity()
220
    {
221
        $this->setUp('createValueObject', __CLASS__, false, false);
222
223
        /** @var HydrationContextInterface $context */
224
        $context = $this->createMock(HydrationContextInterface::class);
225
        $context->method('getEntityClass')->willReturn(EntityExample::class);
226
227
        /** @var array<string> $dataFromAdditionalColumns */
228
        $dataFromAdditionalColumns = array(
229
            'lorem' => 'ipsum',
230
            'dolor' => 'sit amet'
231
        );
232
233
        /** @var ValueObjectExample $expectedResult */
234
        $expectedResult = $this->createMock(ValueObjectExample::class);
235
236
        self::$valueObjectToCreate = $expectedResult;
237
238
        /** @var mixed $actualResult */
239
        $actualResult = $this->callDefinition->execute(
240
            $context,
241
            $dataFromAdditionalColumns
242
        );
243
244
        $this->assertSame($expectedResult, $actualResult);
245
    }
246
247
    public static function createValueObject()
248
    {
249
        return self::$valueObjectToCreate;
250
    }
251
252
    /**
253
     * @test
254
     */
255
    public function shouldExecuteCallDefinitionOnService()
256
    {
257
        $this->setUp('getLorem', '@foo_service', false, false);
258
259
        /** @var HydrationContextInterface $context */
260
        $context = $this->createMock(HydrationContextInterface::class);
261
        $context->method('getEntityClass')->willReturn(EntityExample::class);
262
263
        /** @var ValueObjectExample $expectedResult */
264
        $expectedResult = $this->createMock(ValueObjectExample::class);
265
266
        /** @var ServiceExample $factoryService */
267
        $factoryService = $this->createMock(ServiceExample::class);
268
269
        /** @var array<string> $dataFromAdditionalColumns */
270
        $dataFromAdditionalColumns = array(
271
            'lorem' => 'ipsum',
272
            'dolor' => 'sit amet'
273
        );
274
275
        /** @var MappingInterface $argumentMapping */
276
        $argumentMapping = $this->createMock(MappingInterface::class);
0 ignored issues
show
The assignment to $argumentMapping is dead and can be removed.
Loading history...
277
278
        $this->argumentMappingA->expects($this->once())->method('resolveValue')->with(
279
            $this->equalTo($context),
280
            $this->equalTo($dataFromAdditionalColumns)
281
        )->willReturn('foo');
282
283
        $factoryService->method('getLorem')->will($this->returnValueMap([
0 ignored issues
show
The method method() does not exist on Addiks\RDMBundle\Tests\Hydration\ServiceExample. ( Ignorable by Annotation )

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

283
        $factoryService->/** @scrutinizer ignore-call */ 
284
                         method('getLorem')->will($this->returnValueMap([

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...
284
            ['foo', $expectedResult],
285
        ]));
286
287
        $this->container->method('get')->will($this->returnValueMap([
288
            ['foo_service', ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, $factoryService],
289
        ]));
290
291
        /** @var mixed $actualResult */
292
        $actualResult = $this->callDefinition->execute(
293
            $context,
294
            $dataFromAdditionalColumns
295
        );
296
297
        $this->assertSame($expectedResult, $actualResult);
298
    }
299
300
    /**
301
     * @test
302
     */
303
    public function shouldWakeUpCall()
304
    {
305
        /** @var ContainerInterface $container */
306
        $container = $this->createMock(ContainerInterface::class);
307
308
        /** @var HydrationContextInterface $context */
309
        $context = $this->createMock(HydrationContextInterface::class);
310
311
        $this->setUp("get", "@some_service", false, false);
312
        
313
        $this->argumentMappingA->method('resolveValue')->willReturn('some_service');
314
315
        $container->method("has")->willReturn(true);
0 ignored issues
show
The method method() does not exist on Symfony\Component\Depend...tion\ContainerInterface. ( Ignorable by Annotation )

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

315
        $container->/** @scrutinizer ignore-call */ 
316
                    method("has")->willReturn(true);

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...
316
        $container->method("get")->willReturn($container);
317
318
        $this->callDefinition->wakeUpCall($container);
319
320
        $this->assertEquals($container, $this->callDefinition->execute($context, []));
321
    }
322
323
    /**
324
     * @test
325
     */
326
    public function shouldSleep()
327
    {
328
        $this->assertEquals([
329
            'objectReference',
330
            'routineName',
331
            'argumentMappings',
332
            'isStaticCall',
333
            'origin',
334
        ], $this->callDefinition->__sleep());
335
    }
336
337
}
338