‪TYPO3CMS  9.5
PropertyMapperTest.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
23 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
24 
28 class ‪PropertyMapperTest extends UnitTestCase
29 {
34 
38  protected ‪$mockConfiguration;
39 
43  protected function ‪setUp()
44  {
45  $this->mockConfigurationBuilder = $this->createMock(\‪TYPO3\CMS\‪Extbase\Property\PropertyMappingConfigurationBuilder::class);
46  $this->mockConfiguration = $this->createMock(\‪TYPO3\CMS\‪Extbase\Property\PropertyMappingConfigurationInterface::class);
47  }
48 
52  public function ‪validSourceTypes()
53  {
54  return [
55  ['someString', 'string'],
56  [42, 'integer'],
57  [3.5, 'float'],
58  [true, 'boolean'],
59  [[], 'array']
60  ];
61  }
62 
69  public function ‪sourceTypeCanBeCorrectlyDetermined($source, $sourceType)
70  {
72  $propertyMapper = $this->getAccessibleMock(\‪TYPO3\CMS\‪Extbase\Property\PropertyMapper::class, ['dummy']);
73  $this->assertEquals($sourceType, $propertyMapper->_call('determineSourceType', $source));
74  }
75 
79  public function ‪invalidSourceTypes()
80  {
81  return [
82  [null],
83  [new \stdClass()],
84  [new \ArrayObject()]
85  ];
86  }
87 
93  public function ‪sourceWhichIsNoSimpleTypeThrowsException($source)
94  {
95  $this->expectException(InvalidSourceException::class);
96  $this->expectExceptionCode(1297773150);
98  $propertyMapper = $this->getAccessibleMock(\‪TYPO3\CMS\‪Extbase\Property\PropertyMapper::class, ['dummy']);
99  $propertyMapper->_call('determineSourceType', $source);
100  }
101 
109  protected function ‪getMockTypeConverter($name = '', $canConvertFrom = true, $properties = [], $typeOfSubObject = '')
110  {
111  $mockTypeConverter = $this->createMock(\‪TYPO3\CMS\‪Extbase\Property\TypeConverterInterface::class);
112  $mockTypeConverter->_name = $name;
113  $mockTypeConverter->expects($this->any())->method('canConvertFrom')->will($this->returnValue($canConvertFrom));
114  $mockTypeConverter->expects($this->any())->method('convertFrom')->will($this->returnValue($name));
115  $mockTypeConverter->expects($this->any())->method('getSourceChildPropertiesToBeConverted')->will($this->returnValue($properties));
116  $mockTypeConverter->expects($this->any())->method('getTypeOfChildProperty')->will($this->returnValue($typeOfSubObject));
117  return $mockTypeConverter;
118  }
119 
124  {
125  $mockTypeConverter = $this->‪getMockTypeConverter();
126  $this->mockConfiguration->expects($this->any())->method('getTypeConverter')->will($this->returnValue($mockTypeConverter));
128  $propertyMapper = $this->getAccessibleMock(\‪TYPO3\CMS\‪Extbase\Property\PropertyMapper::class, ['dummy']);
129  $this->assertSame($mockTypeConverter, $propertyMapper->_call('findTypeConverter', 'someSource', 'someTargetType', $this->mockConfiguration));
130  }
131 
136  public function ‪dataProviderForFindTypeConverter()
137  {
138  return [
139  ['someStringSource', 'string', [
140  'string' => [
141  'string' => [
142  10 => $this->‪getMockTypeConverter('string2string,prio10'),
143  1 => $this->‪getMockTypeConverter('string2string,prio1'),
144  ]
145  ]], 'string2string,prio10'
146  ],
147  [['some' => 'array'], 'string', [
148  'array' => [
149  'string' => [
150  10 => $this->‪getMockTypeConverter('array2string,prio10'),
151  1 => $this->‪getMockTypeConverter('array2string,prio1'),
152  ]
153  ]], 'array2string,prio10'
154  ],
155  ['someStringSource', 'bool', [
156  'string' => [
157  'boolean' => [
158  10 => $this->‪getMockTypeConverter('string2boolean,prio10'),
159  1 => $this->‪getMockTypeConverter('string2boolean,prio1'),
160  ]
161  ]], 'string2boolean,prio10'
162  ],
163  ['someStringSource', 'int', [
164  'string' => [
165  'integer' => [
166  10 => $this->‪getMockTypeConverter('string2integer,prio10'),
167  1 => $this->‪getMockTypeConverter('string2integer,prio1'),
168  ],
169  ]], 'string2integer,prio10'
170  ]
171  ];
172  }
173 
182  public function ‪findTypeConverterShouldReturnHighestPriorityTypeConverterForSimpleType($source, $targetType, $typeConverters, $expectedTypeConverter)
183  {
184  $propertyMapper = $this->getAccessibleMock(\‪TYPO3\CMS\‪Extbase\Property\PropertyMapper::class, ['dummy']);
185  $propertyMapper->_set('typeConverters', $typeConverters);
186  $actualTypeConverter = $propertyMapper->_call('findTypeConverter', $source, $targetType, $this->mockConfiguration);
187  $this->assertSame($expectedTypeConverter, $actualTypeConverter->_name);
188  }
189 
194  {
195  $data = [];
196 
197  $className2 = DataProviderTwo::class;
198  $className3 = DataProviderThree::class;
199 
200  $interfaceName1 = DataProviderOneInterface::class;
201  $interfaceName2 = DataProviderTwoInterface::class;
202  $interfaceName3 = DataProviderThreeInterface::class;
203 
204  // The most specific converter should win
205  $data[] = [
206  'target' => $className3,
207  'expectedConverter' => 'Class3Converter',
208  'typeConverters' => [
209  $className2 => [0 => $this->‪getMockTypeConverter('Class2Converter')],
210  $className3 => [0 => $this->‪getMockTypeConverter('Class3Converter')],
211 
212  $interfaceName1 => [0 => $this->‪getMockTypeConverter('Interface1Converter')],
213  $interfaceName2 => [0 => $this->‪getMockTypeConverter('Interface2Converter')],
214  $interfaceName3 => [0 => $this->‪getMockTypeConverter('Interface3Converter')],
215  ]
216  ];
217 
218  // In case the most specific converter does not want to handle this conversion, the second one is taken.
219  $data[] = [
220  'target' => $className3,
221  'expectedConverter' => 'Class2Converter',
222  'typeConverters' => [
223  $className2 => [0 => $this->‪getMockTypeConverter('Class2Converter')],
224  $className3 => [0 => $this->‪getMockTypeConverter('Class3Converter', false)],
225 
226  $interfaceName1 => [0 => $this->‪getMockTypeConverter('Interface1Converter')],
227  $interfaceName2 => [0 => $this->‪getMockTypeConverter('Interface2Converter')],
228  $interfaceName3 => [0 => $this->‪getMockTypeConverter('Interface3Converter')],
229  ]
230  ];
231 
232  // In case there is no most-specific-converter, we climb ub the type hierarchy
233  $data[] = [
234  'target' => $className3,
235  'expectedConverter' => 'Class2Converter-HighPriority',
236  'typeConverters' => [
237  $className2 => [0 => $this->‪getMockTypeConverter('Class2Converter'), 10 => $this->‪getMockTypeConverter('Class2Converter-HighPriority')]
238  ]
239  ];
240 
241  // If no parent class converter wants to handle it, we ask for all interface converters.
242  $data[] = [
243  'target' => $className3,
244  'expectedConverter' => 'Interface1Converter',
245  'typeConverters' => [
246  $className2 => [0 => $this->‪getMockTypeConverter('Class2Converter', false), 10 => $this->‪getMockTypeConverter('Class2Converter-HighPriority', false)],
247 
248  $interfaceName1 => [4 => $this->‪getMockTypeConverter('Interface1Converter')],
249  $interfaceName2 => [1 => $this->‪getMockTypeConverter('Interface2Converter')],
250  $interfaceName3 => [2 => $this->‪getMockTypeConverter('Interface3Converter')],
251  ]
252  ];
253 
254  // If two interface converters have the same priority, an exception is thrown.
255  $data[] = [
256  'target' => $className3,
257  'expectedConverter' => 'Interface1Converter',
258  'typeConverters' => [
259  $className2 => [0 => $this->‪getMockTypeConverter('Class2Converter', false), 10 => $this->‪getMockTypeConverter('Class2Converter-HighPriority', false)],
260 
261  $interfaceName1 => [4 => $this->‪getMockTypeConverter('Interface1Converter')],
262  $interfaceName2 => [2 => $this->‪getMockTypeConverter('Interface2Converter')],
263  $interfaceName3 => [2 => $this->‪getMockTypeConverter('Interface3Converter')],
264  ],
265  'shouldFailWithException' => \TYPO3\CMS\Extbase\Property\Exception\DuplicateTypeConverterException::class
266  ];
267 
268  // If no interface converter wants to handle it, a converter for "object" is looked up.
269  $data[] = [
270  'target' => $className3,
271  'expectedConverter' => 'GenericObjectConverter-HighPriority',
272  'typeConverters' => [
273  $className2 => [0 => $this->‪getMockTypeConverter('Class2Converter', false), 10 => $this->‪getMockTypeConverter('Class2Converter-HighPriority', false)],
274 
275  $interfaceName1 => [4 => $this->‪getMockTypeConverter('Interface1Converter', false)],
276  $interfaceName2 => [3 => $this->‪getMockTypeConverter('Interface2Converter', false)],
277  $interfaceName3 => [2 => $this->‪getMockTypeConverter('Interface3Converter', false)],
278  'object' => [1 => $this->‪getMockTypeConverter('GenericObjectConverter'), 10 => $this->‪getMockTypeConverter('GenericObjectConverter-HighPriority')]
279  ],
280  ];
281 
282  // If the target is no valid class name and no simple type, an exception is thrown
283  $data[] = [
284  'target' => 'SomeNotExistingClassName',
285  'expectedConverter' => 'GenericObjectConverter-HighPriority',
286  'typeConverters' => [],
287  'shouldFailWithException' => \TYPO3\CMS\Extbase\Property\Exception\InvalidTargetException::class
288  ];
289 
290  // if the type converter is not found, we expect an exception
291  $data[] = [
292  'target' => $className3,
293  'expectedConverter' => 'Class3Converter',
294  'typeConverters' => [],
295  'shouldFailWithException' => \TYPO3\CMS\Extbase\Property\Exception\TypeConverterException::class
296  ];
297 
298  // If The target type is no string, we expect an exception.
299  $data[] = [
300  'target' => new \stdClass(),
301  'expectedConverter' => '',
302  'typeConverters' => [],
303  'shouldFailWithException' => \TYPO3\CMS\Extbase\Property\Exception\InvalidTargetException::class
304  ];
305  return $data;
306  }
307 
317  public function ‪findTypeConverterShouldReturnConverterForTargetObjectIfItExists($targetClass, $expectedTypeConverter, $typeConverters, $shouldFailWithException = false)
318  {
319  $propertyMapper = $this->getAccessibleMock(\‪TYPO3\CMS\‪Extbase\Property\PropertyMapper::class, ['dummy']);
320  $propertyMapper->_set('typeConverters', ['string' => $typeConverters]);
321  try {
322  $actualTypeConverter = $propertyMapper->_call('findTypeConverter', 'someSourceString', $targetClass, $this->mockConfiguration);
323  if ($shouldFailWithException) {
324  $this->fail('Expected exception ' . $shouldFailWithException . ' which was not thrown.');
325  }
326  $this->assertSame($expectedTypeConverter, $actualTypeConverter->_name);
327  } catch (\‪Exception $e) {
328  if ($shouldFailWithException === false) {
329  throw $e;
330  }
331  $this->assertInstanceOf($shouldFailWithException, $e);
332  }
333  }
334 
339  {
340  $propertyMapper = $this->getAccessibleMock(\‪TYPO3\CMS\‪Extbase\Property\PropertyMapper::class, ['dummy']);
341  $this->inject($propertyMapper, 'configurationBuilder', $this->mockConfigurationBuilder);
342 
343  $this->mockConfigurationBuilder->expects($this->once())->method('build')->will($this->returnValue($this->mockConfiguration));
344 
345  $converter = $this->‪getMockTypeConverter('string2string');
346  $typeConverters = [
347  'string' => [
348  'string' => [10 => $converter]
349  ]
350  ];
351 
352  $propertyMapper->_set('typeConverters', $typeConverters);
353  $this->assertEquals('string2string', $propertyMapper->convert('source', 'string'));
354  }
355 
360  {
362  $propertyMapper = $this->getAccessibleMock(\‪TYPO3\CMS\‪Extbase\Property\PropertyMapper::class, ['dummy']);
363  $this->assertNull($propertyMapper->_call('findFirstEligibleTypeConverterInObjectHierarchy', 'source', 'unknownSourceType', \‪TYPO3\CMS\‪Extbase\Core\Bootstrap::class));
364  }
365 
370  {
371  $source = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
372  $targetType = \TYPO3\CMS\Extbase\Persistence\ObjectStorage::class;
373  $propertyPath = '';
374  $propertyMapper = $this->getAccessibleMock(\‪TYPO3\CMS\‪Extbase\Property\PropertyMapper::class, ['dummy']);
375  $this->assertSame($source, $propertyMapper->_callRef('doMapping', $source, $targetType, $this->mockConfiguration, $propertyPath));
376  }
377 
382  {
383  $source = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
384  $targetType = \TYPO3\CMS\Extbase\Persistence\ObjectStorage::class . '<SomeEntity>';
385  $propertyPath = '';
386  $propertyMapper = $this->getAccessibleMock(\‪TYPO3\CMS\‪Extbase\Property\PropertyMapper::class, ['dummy']);
387  $this->assertSame($source, $propertyMapper->_callRef('doMapping', $source, $targetType, $this->mockConfiguration, $propertyPath));
388  }
389 
394  {
395  $source = ['firstProperty' => 1, 'secondProperty' => 2];
396  $typeConverters = [
397  'array' => [
398  'stdClass' => [10 => $this->‪getMockTypeConverter('array2object', true, $source, 'integer')]
399  ],
400  'integer' => [
401  'integer' => [10 => $this->‪getMockTypeConverter('integer2integer')]
402  ]
403  ];
404  $configuration = new \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration();
405 
406  $propertyMapper = $this->getAccessibleMock(\‪TYPO3\CMS\‪Extbase\Property\PropertyMapper::class, ['dummy']);
407  $propertyMapper->_set('typeConverters', $typeConverters);
408 
409  $propertyMapper->convert($source, 'stdClass', $configuration->allowProperties('firstProperty')->skipProperties('secondProperty'));
410  }
411 
416  {
417  $source = ['firstProperty' => 1, 'secondProperty' => 2];
418  $typeConverters = [
419  'array' => [
420  'stdClass' => [10 => $this->‪getMockTypeConverter('array2object', true, $source, 'integer')]
421  ],
422  'integer' => [
423  'integer' => [10 => $this->‪getMockTypeConverter('integer2integer')]
424  ]
425  ];
426  $configuration = new \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration();
427 
428  $propertyMapper = $this->getAccessibleMock(\‪TYPO3\CMS\‪Extbase\Property\PropertyMapper::class, ['dummy']);
429  $propertyMapper->_set('typeConverters', $typeConverters);
430 
431  $propertyMapper->convert($source, 'stdClass', $configuration->allowProperties('firstProperty')->skipUnknownProperties());
432  }
433 }
‪TYPO3\CMS\Extbase\Tests\Unit\Property\Fixtures\DataProviderThree
Definition: DataProviderThree.php:21
‪TYPO3\CMS\Extbase\Tests\Unit\Property\Fixtures\DataProviderThreeInterface
Definition: DataProviderThreeInterface.php:21
‪TYPO3\CMS\Extbase\Tests\Unit\Property\PropertyMapperTest\invalidSourceTypes
‪array invalidSourceTypes()
Definition: PropertyMapperTest.php:77
‪TYPO3\CMS\Extbase\Annotation
Definition: IgnoreValidation.php:4
‪TYPO3\CMS\Extbase\Tests\Unit\Property\PropertyMapperTest\sourceTypeCanBeCorrectlyDetermined
‪sourceTypeCanBeCorrectlyDetermined($source, $sourceType)
Definition: PropertyMapperTest.php:67
‪TYPO3
‪TYPO3\CMS\Extbase\Tests\Unit\Property\PropertyMapperTest\findTypeConverterShouldReturnConverterForTargetObjectIfItExists
‪findTypeConverterShouldReturnConverterForTargetObjectIfItExists($targetClass, $expectedTypeConverter, $typeConverters, $shouldFailWithException=false)
Definition: PropertyMapperTest.php:315
‪TYPO3\CMS\Extbase\Tests\Unit\Property\PropertyMapperTest\findFirstEligibleTypeConverterInObjectHierarchyShouldReturnNullIfSourceTypeIsUnknown
‪findFirstEligibleTypeConverterInObjectHierarchyShouldReturnNullIfSourceTypeIsUnknown()
Definition: PropertyMapperTest.php:357
‪TYPO3\CMS\Extbase\Tests\Unit\Property\PropertyMapperTest\convertSkipsUnknownPropertiesIfConfiguredTo
‪convertSkipsUnknownPropertiesIfConfiguredTo()
Definition: PropertyMapperTest.php:413
‪TYPO3\CMS\Extbase\Tests\Unit\Property\PropertyMapperTest\sourceWhichIsNoSimpleTypeThrowsException
‪sourceWhichIsNoSimpleTypeThrowsException($source)
Definition: PropertyMapperTest.php:91
‪TYPO3\CMS\Extbase\Tests\Unit\Property\PropertyMapperTest\convertShouldAskConfigurationBuilderForDefaultConfiguration
‪convertShouldAskConfigurationBuilderForDefaultConfiguration()
Definition: PropertyMapperTest.php:336
‪TYPO3\CMS\Extbase\Tests\Unit\Property\PropertyMapperTest\dataProviderForObjectTypeConverters
‪array dataProviderForObjectTypeConverters()
Definition: PropertyMapperTest.php:191
‪TYPO3\CMS\Extbase\Exception
Definition: Exception.php:23
‪TYPO3\CMS\Extbase\Tests\Unit\Property\Fixtures\DataProviderTwo
Definition: DataProviderTwo.php:21
‪TYPO3\CMS\Extbase\Tests\Unit\Property\PropertyMapperTest
Definition: PropertyMapperTest.php:29
‪TYPO3\CMS\Extbase\Tests\Unit\Property\Fixtures\DataProviderOneInterface
Definition: DataProviderOneInterface.php:21
‪TYPO3\CMS\Extbase\Tests\Unit\Property
‪TYPO3\CMS\Extbase\Tests\Unit\Property\PropertyMapperTest\findTypeConverterShouldReturnTypeConverterFromConfigurationIfItIsSet
‪findTypeConverterShouldReturnTypeConverterFromConfigurationIfItIsSet()
Definition: PropertyMapperTest.php:121
‪TYPO3\CMS\Extbase\Tests\Unit\Property\PropertyMapperTest\setUp
‪setUp()
Definition: PropertyMapperTest.php:41
‪TYPO3\CMS\Extbase\Tests\Unit\Property\Fixtures\DataProviderTwoInterface
Definition: DataProviderTwoInterface.php:21
‪TYPO3\CMS\Extbase\Tests\Unit\Property\PropertyMapperTest\getMockTypeConverter
‪PHPUnit_Framework_MockObject_MockObject getMockTypeConverter($name='', $canConvertFrom=true, $properties=[], $typeOfSubObject='')
Definition: PropertyMapperTest.php:107
‪TYPO3\CMS\Extbase\Tests\Unit\Property\PropertyMapperTest\dataProviderForFindTypeConverter
‪array dataProviderForFindTypeConverter()
Definition: PropertyMapperTest.php:134
‪TYPO3\CMS\Extbase\Tests\Unit\Property\PropertyMapperTest\$mockConfiguration
‪TYPO3 CMS Extbase Property PropertyMappingConfigurationInterface PHPUnit_Framework_MockObject_MockObject $mockConfiguration
Definition: PropertyMapperTest.php:36
‪TYPO3\CMS\Extbase\Tests\Unit\Property\PropertyMapperTest\findTypeConverterShouldReturnHighestPriorityTypeConverterForSimpleType
‪findTypeConverterShouldReturnHighestPriorityTypeConverterForSimpleType($source, $targetType, $typeConverters, $expectedTypeConverter)
Definition: PropertyMapperTest.php:180
‪TYPO3\CMS\Extbase\Tests\Unit\Property\PropertyMapperTest\convertSkipsPropertiesIfConfiguredTo
‪convertSkipsPropertiesIfConfiguredTo()
Definition: PropertyMapperTest.php:391
‪TYPO3\CMS\Extbase\Tests\Unit\Property\PropertyMapperTest\doMappingReturnsSourceUnchangedIfAlreadyConverted
‪doMappingReturnsSourceUnchangedIfAlreadyConverted()
Definition: PropertyMapperTest.php:367
‪TYPO3\CMS\Extbase\Tests\Unit\Property\PropertyMapperTest\validSourceTypes
‪array validSourceTypes()
Definition: PropertyMapperTest.php:50
‪TYPO3\CMS\Extbase\Tests\Unit\Property\PropertyMapperTest\$mockConfigurationBuilder
‪TYPO3 CMS Extbase Property PropertyMappingConfigurationBuilder PHPUnit_Framework_MockObject_MockObject $mockConfigurationBuilder
Definition: PropertyMapperTest.php:32
‪TYPO3\CMS\Extbase\Tests\Unit\Property\PropertyMapperTest\doMappingReturnsSourceUnchangedIfAlreadyConvertedToCompositeType
‪doMappingReturnsSourceUnchangedIfAlreadyConvertedToCompositeType()
Definition: PropertyMapperTest.php:379
‪TYPO3\CMS\Extbase\Property\Exception\InvalidSourceException
Definition: InvalidSourceException.php:21