PageRenderTime 49ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Symfony/Component/Form/Tests/Extension/Core/DataMapper/PropertyPathMapperTest.php

http://github.com/symfony/symfony
PHP | 348 lines | 254 code | 74 blank | 20 comment | 0 complexity | 750bc9051f9ab285155f58ba62948aff MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Form\Tests\Extension\Core\DataMapper;
  11. use PHPUnit\Framework\TestCase;
  12. use Symfony\Component\EventDispatcher\EventDispatcher;
  13. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  14. use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
  15. use Symfony\Component\Form\Form;
  16. use Symfony\Component\Form\FormConfigBuilder;
  17. use Symfony\Component\PropertyAccess\PropertyAccess;
  18. use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
  19. use Symfony\Component\PropertyAccess\PropertyPath;
  20. class PropertyPathMapperTest extends TestCase
  21. {
  22. /**
  23. * @var PropertyPathMapper
  24. */
  25. private $mapper;
  26. /**
  27. * @var EventDispatcherInterface
  28. */
  29. private $dispatcher;
  30. /**
  31. * @var PropertyAccessorInterface
  32. */
  33. private $propertyAccessor;
  34. protected function setUp(): void
  35. {
  36. $this->dispatcher = new EventDispatcher();
  37. $this->propertyAccessor = PropertyAccess::createPropertyAccessor();
  38. $this->mapper = new PropertyPathMapper($this->propertyAccessor);
  39. }
  40. public function testMapDataToFormsPassesObjectRefIfByReference()
  41. {
  42. $car = new \stdClass();
  43. $engine = new \stdClass();
  44. $car->engine = $engine;
  45. $propertyPath = new PropertyPath('engine');
  46. $config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
  47. $config->setByReference(true);
  48. $config->setPropertyPath($propertyPath);
  49. $form = new Form($config);
  50. $this->mapper->mapDataToForms($car, [$form]);
  51. $this->assertSame($engine, $form->getData());
  52. }
  53. public function testMapDataToFormsPassesObjectCloneIfNotByReference()
  54. {
  55. $car = new \stdClass();
  56. $engine = new \stdClass();
  57. $engine->brand = 'Rolls-Royce';
  58. $car->engine = $engine;
  59. $propertyPath = new PropertyPath('engine');
  60. $config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
  61. $config->setByReference(false);
  62. $config->setPropertyPath($propertyPath);
  63. $form = new Form($config);
  64. $this->mapper->mapDataToForms($car, [$form]);
  65. $this->assertNotSame($engine, $form->getData());
  66. $this->assertEquals($engine, $form->getData());
  67. }
  68. public function testMapDataToFormsIgnoresEmptyPropertyPath()
  69. {
  70. $car = new \stdClass();
  71. $config = new FormConfigBuilder(null, '\stdClass', $this->dispatcher);
  72. $config->setByReference(true);
  73. $form = new Form($config);
  74. $this->assertNull($form->getPropertyPath());
  75. $this->mapper->mapDataToForms($car, [$form]);
  76. $this->assertNull($form->getData());
  77. }
  78. public function testMapDataToFormsIgnoresUnmapped()
  79. {
  80. $car = new \stdClass();
  81. $car->engine = new \stdClass();
  82. $propertyPath = new PropertyPath('engine');
  83. $config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
  84. $config->setByReference(true);
  85. $config->setMapped(false);
  86. $config->setPropertyPath($propertyPath);
  87. $form = new Form($config);
  88. $this->mapper->mapDataToForms($car, [$form]);
  89. $this->assertNull($form->getData());
  90. }
  91. public function testMapDataToFormsSetsDefaultDataIfPassedDataIsNull()
  92. {
  93. $default = new \stdClass();
  94. $propertyPath = new PropertyPath('engine');
  95. $config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
  96. $config->setByReference(true);
  97. $config->setPropertyPath($propertyPath);
  98. $config->setData($default);
  99. $form = new Form($config);
  100. $this->mapper->mapDataToForms(null, [$form]);
  101. $this->assertSame($default, $form->getData());
  102. }
  103. public function testMapDataToFormsSetsDefaultDataIfPassedDataIsEmptyArray()
  104. {
  105. $default = new \stdClass();
  106. $propertyPath = new PropertyPath('engine');
  107. $config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
  108. $config->setByReference(true);
  109. $config->setPropertyPath($propertyPath);
  110. $config->setData($default);
  111. $form = new Form($config);
  112. $this->mapper->mapDataToForms([], [$form]);
  113. $this->assertSame($default, $form->getData());
  114. }
  115. public function testMapFormsToDataWritesBackIfNotByReference()
  116. {
  117. $car = new \stdClass();
  118. $car->engine = new \stdClass();
  119. $engine = new \stdClass();
  120. $engine->brand = 'Rolls-Royce';
  121. $propertyPath = new PropertyPath('engine');
  122. $config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
  123. $config->setByReference(false);
  124. $config->setPropertyPath($propertyPath);
  125. $config->setData($engine);
  126. $form = new SubmittedForm($config);
  127. $this->mapper->mapFormsToData([$form], $car);
  128. $this->assertEquals($engine, $car->engine);
  129. $this->assertNotSame($engine, $car->engine);
  130. }
  131. public function testMapFormsToDataWritesBackIfByReferenceButNoReference()
  132. {
  133. $car = new \stdClass();
  134. $car->engine = new \stdClass();
  135. $engine = new \stdClass();
  136. $propertyPath = new PropertyPath('engine');
  137. $config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
  138. $config->setByReference(true);
  139. $config->setPropertyPath($propertyPath);
  140. $config->setData($engine);
  141. $form = new SubmittedForm($config);
  142. $this->mapper->mapFormsToData([$form], $car);
  143. $this->assertSame($engine, $car->engine);
  144. }
  145. public function testMapFormsToDataWritesBackIfByReferenceAndReference()
  146. {
  147. $car = new \stdClass();
  148. $car->engine = 'BMW';
  149. $propertyPath = new PropertyPath('engine');
  150. $config = new FormConfigBuilder('engine', null, $this->dispatcher);
  151. $config->setByReference(true);
  152. $config->setPropertyPath($propertyPath);
  153. $config->setData('Rolls-Royce');
  154. $form = new SubmittedForm($config);
  155. $car->engine = 'Rolls-Royce';
  156. $this->mapper->mapFormsToData([$form], $car);
  157. $this->assertSame('Rolls-Royce', $car->engine);
  158. }
  159. public function testMapFormsToDataIgnoresUnmapped()
  160. {
  161. $initialEngine = new \stdClass();
  162. $car = new \stdClass();
  163. $car->engine = $initialEngine;
  164. $engine = new \stdClass();
  165. $propertyPath = new PropertyPath('engine');
  166. $config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
  167. $config->setByReference(true);
  168. $config->setPropertyPath($propertyPath);
  169. $config->setData($engine);
  170. $config->setMapped(false);
  171. $form = new SubmittedForm($config);
  172. $this->mapper->mapFormsToData([$form], $car);
  173. $this->assertSame($initialEngine, $car->engine);
  174. }
  175. public function testMapFormsToDataIgnoresUnsubmittedForms()
  176. {
  177. $initialEngine = new \stdClass();
  178. $car = new \stdClass();
  179. $car->engine = $initialEngine;
  180. $engine = new \stdClass();
  181. $propertyPath = new PropertyPath('engine');
  182. $config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
  183. $config->setByReference(true);
  184. $config->setPropertyPath($propertyPath);
  185. $config->setData($engine);
  186. $form = new Form($config);
  187. $this->mapper->mapFormsToData([$form], $car);
  188. $this->assertSame($initialEngine, $car->engine);
  189. }
  190. public function testMapFormsToDataIgnoresEmptyData()
  191. {
  192. $initialEngine = new \stdClass();
  193. $car = new \stdClass();
  194. $car->engine = $initialEngine;
  195. $propertyPath = new PropertyPath('engine');
  196. $config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
  197. $config->setByReference(true);
  198. $config->setPropertyPath($propertyPath);
  199. $config->setData(null);
  200. $form = new Form($config);
  201. $this->mapper->mapFormsToData([$form], $car);
  202. $this->assertSame($initialEngine, $car->engine);
  203. }
  204. public function testMapFormsToDataIgnoresUnsynchronized()
  205. {
  206. $initialEngine = new \stdClass();
  207. $car = new \stdClass();
  208. $car->engine = $initialEngine;
  209. $engine = new \stdClass();
  210. $propertyPath = new PropertyPath('engine');
  211. $config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
  212. $config->setByReference(true);
  213. $config->setPropertyPath($propertyPath);
  214. $config->setData($engine);
  215. $form = new NotSynchronizedForm($config);
  216. $this->mapper->mapFormsToData([$form], $car);
  217. $this->assertSame($initialEngine, $car->engine);
  218. }
  219. public function testMapFormsToDataIgnoresDisabled()
  220. {
  221. $initialEngine = new \stdClass();
  222. $car = new \stdClass();
  223. $car->engine = $initialEngine;
  224. $engine = new \stdClass();
  225. $propertyPath = new PropertyPath('engine');
  226. $config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
  227. $config->setByReference(true);
  228. $config->setPropertyPath($propertyPath);
  229. $config->setData($engine);
  230. $config->setDisabled(true);
  231. $form = new Form($config);
  232. $this->mapper->mapFormsToData([$form], $car);
  233. $this->assertSame($initialEngine, $car->engine);
  234. }
  235. /**
  236. * @dataProvider provideDate
  237. */
  238. public function testMapFormsToDataDoesNotChangeEqualDateTimeInstance($date)
  239. {
  240. $article = [];
  241. $publishedAt = $date;
  242. $publishedAtValue = clone $publishedAt;
  243. $article['publishedAt'] = $publishedAtValue;
  244. $propertyPath = new PropertyPath('[publishedAt]');
  245. $config = new FormConfigBuilder('publishedAt', \get_class($publishedAt), $this->dispatcher);
  246. $config->setByReference(false);
  247. $config->setPropertyPath($propertyPath);
  248. $config->setData($publishedAt);
  249. $form = new SubmittedForm($config);
  250. $this->mapper->mapFormsToData([$form], $article);
  251. $this->assertSame($publishedAtValue, $article['publishedAt']);
  252. }
  253. public function provideDate()
  254. {
  255. return [
  256. [new \DateTime()],
  257. [new \DateTimeImmutable()],
  258. ];
  259. }
  260. }
  261. class SubmittedForm extends Form
  262. {
  263. public function isSubmitted(): bool
  264. {
  265. return true;
  266. }
  267. }
  268. class NotSynchronizedForm extends Form
  269. {
  270. public function isSynchronized(): bool
  271. {
  272. return false;
  273. }
  274. }