Completed
Push — master ( 77cc29...840912 )
by Gerrit
10:19
created

ObjectMappingTest::shouldCollectDBALColumns()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 7
nc 1
nop 0
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\ObjectMapping;
15
use Addiks\RDMBundle\Mapping\CallDefinitionInterface;
16
use Addiks\RDMBundle\Tests\ValueObjectExample;
17
use Addiks\RDMBundle\Mapping\MappingInterface;
18
use Doctrine\DBAL\Schema\Column;
19
use Addiks\RDMBundle\Exception\FailedRDMAssertionExceptionInterface;
20
use Addiks\RDMBundle\Hydration\HydrationContextInterface;
21
use Addiks\RDMBundle\Tests\Hydration\EntityExample;
22
use Doctrine\DBAL\Types\Type;
23
use Doctrine\ORM\EntityManagerInterface;
24
use Doctrine\DBAL\Connection;
25
use Doctrine\DBAL\Platforms\AbstractPlatform;
26
use ReflectionClass;
27
use Symfony\Component\DependencyInjection\ContainerInterface;
28
29
final class ObjectMappingTest extends TestCase
30
{
31
32
    /**
33
     * @var ObjectMapping
34
     */
35
    private $objectMapping;
36
37
    /**
38
     * @var CallDefinitionInterface
39
     */
40
    private $factory;
41
42
    /**
43
     * @var CallDefinitionInterface
44
     */
45
    private $serializer;
46
47
    /**
48
     * @var MappingInterface
49
     */
50
    private $fieldMappingA;
51
52
    /**
53
     * @var MappingInterface
54
     */
55
    private $fieldMappingB;
56
57
    /**
58
     * @var Column
59
     */
60
    private $column;
61
62
    public function setUp(
63
        string $className = ValueObjectExample::class,
64
        bool $hasFieldMappingB = true,
65
        bool $useFactory = true,
66
        bool $useSerializer = true,
67
        string $id = "some_id",
68
        string $referenceId = "some_reference",
69
        string $firstMappingName = "lorem"
70
    ) {
71
        $this->factory = $this->createMock(CallDefinitionInterface::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createMock(\Addik...nitionInterface::class) of type object<PHPUnit\Framework\MockObject\MockObject> is incompatible with the declared type object<Addiks\RDMBundle\...allDefinitionInterface> of property $factory.

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...
72
        $this->serializer = $this->createMock(CallDefinitionInterface::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createMock(\Addik...nitionInterface::class) of type object<PHPUnit\Framework\MockObject\MockObject> is incompatible with the declared type object<Addiks\RDMBundle\...allDefinitionInterface> of property $serializer.

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...
73
        $this->fieldMappingA = $this->createMock(MappingInterface::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createMock(\Addik...appingInterface::class) of type object<PHPUnit\Framework\MockObject\MockObject> is incompatible with the declared type object<Addiks\RDMBundle\Mapping\MappingInterface> of property $fieldMappingA.

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...
74
        $this->fieldMappingB = $this->createMock(MappingInterface::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createMock(\Addik...appingInterface::class) of type object<PHPUnit\Framework\MockObject\MockObject> is incompatible with the declared type object<Addiks\RDMBundle\Mapping\MappingInterface> of property $fieldMappingB.

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...
75
        $this->column = $this->createMock(Column::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createMock(\Doctr...L\Schema\Column::class) of type object<PHPUnit\Framework\MockObject\MockObject> is incompatible with the declared type object<Doctrine\DBAL\Schema\Column> of property $column.

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...
76
77
        /** @var array<string,MappingInterface> $fieldMappings */
78
        $fieldMappings = [
79
            $firstMappingName => $this->fieldMappingA,
80
        ];
81
82
        if ($hasFieldMappingB) {
83
            $fieldMappings['dolor'] = $this->fieldMappingB;
84
        }
85
86
        /** @var CallDefinitionInterface|null $factory */
87
        $factory = null;
88
89
        /** @var CallDefinitionInterface|null $serializer */
90
        $serializer = null;
91
92
        if ($useFactory) {
93
            $factory = $this->factory;
94
        }
95
96
        if ($useSerializer) {
97
            $serializer = $this->serializer;
98
        }
99
100
        $this->objectMapping = new ObjectMapping(
101
            $className,
102
            $fieldMappings,
103
            $this->column,
0 ignored issues
show
Documentation introduced by
$this->column is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a null|object<Doctrine\DBAL\Schema\Column>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
104
            "some cool origin",
105
            $factory,
0 ignored issues
show
Bug introduced by
It seems like $factory defined by $this->factory on line 93 can also be of type object<PHPUnit\Framework\MockObject\MockObject>; however, Addiks\RDMBundle\Mapping...tMapping::__construct() does only seem to accept null|object<Addiks\RDMBu...allDefinitionInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
106
            $serializer,
0 ignored issues
show
Bug introduced by
It seems like $serializer defined by $this->serializer on line 97 can also be of type object<PHPUnit\Framework\MockObject\MockObject>; however, Addiks\RDMBundle\Mapping...tMapping::__construct() does only seem to accept null|object<Addiks\RDMBu...allDefinitionInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
107
            $id,
108
            $referenceId
109
        );
110
    }
111
112
    /**
113
     * @test
114
     */
115
    public function shouldStoreClassName()
116
    {
117
        $this->assertEquals(ValueObjectExample::class, $this->objectMapping->getClassName());
118
    }
119
120
    /**
121
     * @test
122
     */
123
    public function shouldStoreFieldMappings()
124
    {
125
        $this->assertEquals([
126
            'lorem' => $this->createMock(MappingInterface::class),
127
            'dolor' => $this->createMock(MappingInterface::class),
128
        ], $this->objectMapping->getFieldMappings());
129
    }
130
131
    /**
132
     * @test
133
     */
134
    public function shouldStoreOrigin()
135
    {
136
        $this->assertEquals("some cool origin", $this->objectMapping->describeOrigin());
137
    }
138
139
    /**
140
     * @test
141
     */
142
    public function shouldStoreDBALColumn()
143
    {
144
        $this->assertSame($this->column, $this->objectMapping->getDBALColumn());
145
    }
146
147
    /**
148
     * @test
149
     */
150
    public function shouldStoreId()
151
    {
152
        $this->assertSame("some_id", $this->objectMapping->getId());
153
    }
154
155
    /**
156
     * @test
157
     */
158
    public function shouldStoreReferenceId()
159
    {
160
        $this->assertSame("some_reference", $this->objectMapping->getReferencedId());
161
    }
162
163
    /**
164
     * @test
165
     */
166
    public function shouldCollectDBALColumns()
167
    {
168
        /** @var Column $columnA */
169
        $columnA = $this->createMock(Column::class);
170
171
        /** @var Column $columnB */
172
        $columnB = $this->createMock(Column::class);
173
174
        /** @var array<Column> $expectedColumns */
175
        $expectedColumns = [$columnA, $columnB, $this->column];
176
177
        $this->fieldMappingA->method('collectDBALColumns')->willReturn([$columnA]);
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<Addiks\RDMBundle\Mapping\MappingInterface>.

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...
178
        $this->fieldMappingB->method('collectDBALColumns')->willReturn([$columnB]);
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<Addiks\RDMBundle\Mapping\MappingInterface>.

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...
179
180
        $this->assertEquals($expectedColumns, $this->objectMapping->collectDBALColumns());
181
    }
182
183
    /**
184
     * @test
185
     */
186
    public function shouldStoreFactory()
187
    {
188
        $this->assertSame($this->factory, $this->objectMapping->getFactory());
189
    }
190
191
    /**
192
     * @test
193
     */
194
    public function shouldStoreSerializer()
195
    {
196
        $this->assertSame($this->serializer, $this->objectMapping->getSerializer());
197
    }
198
199
    /**
200
     * @test
201
     */
202
    public function shouldResolveObjectValue()
203
    {
204
        $this->setUp(ValueObjectExample::class, false, true, false, "some_id", "", "amet");
205
206
        /** @var ValueObjectExample $object */
207
        $object = $this->createMock(ValueObjectExample::class);
208
209
        $this->column->expects($this->once())->method("getName")->willReturn("some_column");
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Doctrine\DBAL\Schema\Column>.

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...
210
211
        /** @var HydrationContextInterface $context */
212
        $context = $this->createMock(HydrationContextInterface::class);
213
        $context->method('getEntityClass')->willReturn(EntityExample::class);
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<Addiks\RDMBundle\...rationContextInterface>.

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
        $context->expects($this->once())->method('registerValue')->with(
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Addiks\RDMBundle\...rationContextInterface>.

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...
215
            "some_id",
216
            $object
217
        );
218
219
        /** @var mixed $dataFromAdditionalColumns */
220
        $dataFromAdditionalColumns = array(
221
            'lorem' => 'ipsum',
222
            'dolor' => 'sit amet',
223
            'amet'  => 'EXPECTED',
224
        );
225
226
        $this->factory->method('execute')->willReturn($object);
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<Addiks\RDMBundle\...allDefinitionInterface>.

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...
227
228
        $this->fieldMappingA->expects($this->once())->method('resolveValue')->with(
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Addiks\RDMBundle\Mapping\MappingInterface>.

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...
229
            $this->equalTo($context),
230
            $this->equalTo([
231
                'amet'  => 'EXPECTED',
232
                'lorem' => 'ipsum',
233
                'dolor' => 'sit amet',
234
            ])
235
        )->willReturn("FOO BAR BAZ");
236
237
        /** @var mixed $actualObject */
238
        $actualObject = $this->objectMapping->resolveValue($context, $dataFromAdditionalColumns);
239
240
        $this->assertSame($actualObject, $object);
241
242
        $reflectionClass = new ReflectionClass(ValueObjectExample::class);
243
244
        /** @var ReflectionProperty $reflectionProperty */
245
        $reflectionProperty = $reflectionClass->getProperty("amet");
246
        $reflectionProperty->setAccessible(true);
247
248
        $this->assertEquals("FOO BAR BAZ", $reflectionProperty->getValue($object));
249
    }
250
251
    /**
252
     * @test
253
     */
254
    public function shouldNotLoadFactoryArgumentsWhenDataGiven()
255
    {
256
        $this->setUp(ValueObjectExample::class, false, true, false, "some_id", "");
257
258
        /** @var ValueObjectExample $object */
259
        $object = $this->createMock(ValueObjectExample::class);
260
261
        $this->column->expects($this->never())->method("getName");
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Doctrine\DBAL\Schema\Column>.

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...
262
263
        /** @var HydrationContextInterface $context */
264
        $context = $this->createMock(HydrationContextInterface::class);
265
        $context->method('getEntityClass')->willReturn(EntityExample::class);
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<Addiks\RDMBundle\...rationContextInterface>.

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...
266
        $context->expects($this->once())->method('registerValue')->with(
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Addiks\RDMBundle\...rationContextInterface>.

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...
267
            "some_id",
268
            $object
269
        );
270
271
        $this->factory->method('execute')->willReturn($object);
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<Addiks\RDMBundle\...allDefinitionInterface>.

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...
272
273
        /** @var mixed $dataFromAdditionalColumns */
274
        $dataFromAdditionalColumns = array(
275
            'lorem' => 'ipsum',
276
            'dolor' => 'sit amet',
277
            '' => 'foo'
278
        );
279
280
        $this->fieldMappingA->method('resolveValue')->willReturn("FOO BAR BAZ");
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<Addiks\RDMBundle\Mapping\MappingInterface>.

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...
281
282
        $this->objectMapping->resolveValue($context, $dataFromAdditionalColumns);
283
    }
284
285
    /**
286
     * @test
287
     */
288
    public function shouldRevertObjectValue()
289
    {
290
        $this->setUp(ValueObjectExample::class, false, false, false, "some_id", "", "amet");
291
292
        /** @var HydrationContextInterface $context */
293
        $context = $this->createMock(HydrationContextInterface::class);
294
        $context->method('getEntityClass')->willReturn(EntityExample::class);
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<Addiks\RDMBundle\...rationContextInterface>.

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...
295
        $context->method('getEntityManager')->willReturn($this->createEntityManagerMock());
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<Addiks\RDMBundle\...rationContextInterface>.

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...
296
297
        $actualObject = new ValueObjectExample('foo', 'sit amet');
298
        $actualObject->setAmet('EXPECTED');
299
300
        $this->fieldMappingA->method('revertValue')->will($this->returnValueMap([
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<Addiks\RDMBundle\Mapping\MappingInterface>.

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...
301
            [$context, 'sit amet', ['amet' => "FOO BAR BAZ"]],
302
            [$context, 'EXPECTED', ['amet' => "QWE ASD YXC"]],
303
        ]));
304
305
        /** @var Type $type */
306
        $type = $this->createMock(Type::class);
307
308
        $this->column->method('getType')->willReturn($type);
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<Doctrine\DBAL\Schema\Column>.

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...
309
310
        /** @var array $actualData */
311
        $actualData = $this->objectMapping->revertValue($context, $actualObject);
312
313
        $this->assertEquals(['amet' => "QWE ASD YXC"], $actualData);
314
    }
315
316
    /**
317
     * @test
318
     */
319
    public function shouldFailAssertionOnWrongObject()
320
    {
321
        $this->setUp(ValueObjectExample::class);
322
323
        $dataFromAdditionalColumns = array(
324
            'lorem' => 'ipsum',
325
            'dolor' => 'sit amet',
326
        );
327
328
        /** @var mixed $actualValue */
329
        $actualValue = $this->createMock(EntityExample::class);
330
331
        $this->expectException(FailedRDMAssertionExceptionInterface::class);
332
333
        /** @var HydrationContextInterface $context */
334
        $context = $this->createMock(HydrationContextInterface::class);
335
        $context->method('getEntityClass')->willReturn(EntityExample::class);
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<Addiks\RDMBundle\...rationContextInterface>.

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...
336
337
        $this->objectMapping->assertValue($context, $dataFromAdditionalColumns, $actualValue);
338
    }
339
340 View Code Duplication
    private function createEntityManagerMock(): EntityManagerInterface
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
341
    {
342
        /** @var EntityManagerInterface $entityManager */
343
        $entityManager = $this->createMock(EntityManagerInterface::class);
344
345
        /** @var Connection $connection */
346
        $connection = $this->createMock(Connection::class);
347
348
        $entityManager->method('getConnection')->willReturn($connection);
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<Doctrine\ORM\EntityManagerInterface>.

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...
349
350
        /** @var AbstractPlatform $platform */
351
        $platform = $this->createMock(AbstractPlatform::class);
352
353
        $connection->method('getDatabasePlatform')->willReturn($platform);
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<Doctrine\DBAL\Connection>.

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...
354
355
        return $entityManager;
356
    }
357
358
    /**
359
     * @test
360
     */
361 View Code Duplication
    public function shouldWakeUpInnerMapping()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
362
    {
363
        /** @var ContainerInterface $container */
364
        $container = $this->createMock(ContainerInterface::class);
365
366
        $this->factory->expects($this->once())->method("wakeUpCall")->with(
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Addiks\RDMBundle\...allDefinitionInterface>.

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...
367
            $this->equalTo($container)
368
        );
369
370
        $this->serializer->expects($this->once())->method("wakeUpCall")->with(
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Addiks\RDMBundle\...allDefinitionInterface>.

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...
371
            $this->equalTo($container)
372
        );
373
374
        $this->objectMapping->wakeUpMapping($container);
375
    }
376
377
}
378